This question already has an answer here:
Change opacity on all elements except hovered one
(1 answer)
Closed last month.
in:
p:not(:hover) {
opacity: 0.6;
}
p {
opacity: 1;
}
Which would only highlight what is hovered, but I want to achieve an effect that would lower opacity of objects that aren't being hovered on. how do I do it?
the only "person" I could reach out to as someone new to programming was chatGPT that has failed me after many tries, or maybe it's me who can't spell my requirements correctly.
You don't have to use JavaScript. To make the effect opacity: 0.6 for all items except the current item, you need to assign a hover to the parent item, and simultaneously assign the effect opacity: 1 from the parent with the hover to the current item: div:hover p:hover {}
p {
background: green;
}
div:hover p {
opacity: 0.6;
}
div:hover p:hover {
opacity: 1;
}
<div>
<p>text</p>
<p>text</p>
<p>text</p>
</div>
You're overcomplicating the code. What you want to do is much simpler than it seems. From what I understand you want to set opacity: 1 only to the paragraph with the hover, and the rest set with opacity: .6
CSS
p {
opacity: .6;
}
p:hover {
opacity: 1;
}
With this code, by default all paragraphs will have an opacity of 0.6, and when you hover over them, that particular paragraph will have an opacity of 1.
There would be one simple way of doing it with JavaScript.
const boxItems = Array.from(document.querySelectorAll(".box"))
const setBoxOpacity = () => boxItems.forEach(item => item.classList.add("not-hovered"))
const removeBoxOpacity = () => boxItems.forEach(item => item.classList.remove("not-hovered"))
boxItems.forEach(box => {
box.addEventListener("mouseover", (e) => {
setBoxOpacity()
e.target.classList.remove("not-hovered")
})
})
boxItems.forEach(box => box.addEventListener("mouseout", removeBoxOpacity))
.boxes {
display: flex;
gap: 15px;
}
.box {
border: 1px solid black;
width: 200px;
height: 150px;
background: red;
opacity: 1;
}
.box.not-hovered {
opacity: 0.5;
}
<div class="boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
Related
I am new to animations in CSS and this is my code
#keyframes fadeOut{
0% {opacity: 1;}
100% {opacity: 0;}
}
I want the above code to take effect on #menu only no matter where it is called, For EG: It is called on a button click but only affects the #menu element. Somewhat like and doesn't do anything to the button
button:focus{animation-name: fadeOut;
animation-duration: 4s;}
#keyframes fadeOut{
#menu{0% {opacity: 1;}}
#menu{100% {opacity: 0;}}
}
But the above code is illegal in CSS and hence, I can't use it.
Is there any alternate way to do this.
Thanks in advance.
You can do that by using JavaScript:
Example 1
In this example, we add an event for each element, each event calls the animation function that styles the #menu element.
let menu = document.getElementById('menu');
let btn = document.querySelector('.btn');
let p = document.querySelector('.p');
let box = document.querySelector('.box');
function animateIt(){
menu.style.animation = 'fade 1s';
setTimeout(function(){
menu.style.animation = 'unset';
}, 1000);
}
btn.addEventListener('click', (e) => {
animateIt();
});
p.addEventListener('click', (e) => {
animateIt();
});
box.addEventListener('click', (e) => {
animateIt();
});
#menu {
width: 200px;
height: 200px;
background-color: red;
margin-bottom: 20px;
opacity: 0;
}
.box {
background-color: blue;
color: #fafafa;
width: 200px;
}
#keyframes fade{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div id="menu"></div>
<button class="btn">Click</button>
<p class="p">Or Click Here</p>
<div class="box">Or Click Even Here</div>
Example 2
In this example, we simply add the elements that will have events that animates the #menu in an array of objects with the class name and the event listener for each one. Each element and it's event will basically call the animateIt() function that styles and animates the #menu.
All you have to do is to add a line for each element that will call the animation, including ONLY the class name, and the event that calls it.
// Get the #menu
let menu = document.getElementById('menu');
// Gather the elements in an array of objects including the class name and the event
let elements = [
{class: ".btn", evt: "click"},
{class: ".p", evt: "click"},
{class: ".box", evt: "mouseover"}
];
for(let i = 0; i < elements.length; i++){
// Get the element
let theTarget = document.querySelector(elements[i].class);
// Get the event
let targetEvt = elements[i].evt;
// Add event for each element to call the animation function
theTarget.addEventListener(targetEvt, (e) => {
animateIt();
});
}
// The animation function that styles (animate) the #menu
function animateIt(){
menu.style.animation = 'fade 1s';
setTimeout(function(){
menu.style.animation = 'unset';
}, 1000);
}
#menu {
width: 200px;
height: 200px;
background-color: red;
margin-bottom: 20px;
opacity: 0;
}
.box {
background-color: blue;
color: #fafafa;
width: 200px;
}
#keyframes fade{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<div id="menu"></div>
<button class="btn">Click Here</button>
<p class="p">Or Click Here</p>
<div class="box">Or Hover Here</div>
As i understood , you have to add the animation to your element Like :
/* The animation code */
#keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
/* The element to apply the animation to */
div {
width: 100px;
height: 100px;
background-color: red;
animation-name: example;
animation-duration: 4s;
}
In your case it will be :
#menu {
animation-name: fadeOut;
animation-duration: 4s;
}
You can change 4s to the duration you want.
The demo is quite simple, and similar to the example in the Vue.js docs.
new Vue({
el: '#demo',
data: {
show: true
}
})
p {
width: 100px;
border: 1px solid red;
}
.fade-enter-active,
.fade-leave-active {
transition: all 5s;
}
.fade-enter {
opacity: 0;
width: 500px;
background: red;
}
.fade-enter-to {
background: black
}
.fade-leave {
opacity: 0;
background: red
}
.fade-leave-to {
background: black;
width: 1000px;
opacity: 1
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12"></script>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
The question is, when the leave animation begins, it seems it's removed from the DOM (v-if is false) so quickly that there isn't any animation at all!
But, if I remove opacity, the animation works! Why does opacity matter?
.fade-leave {
/* opacity: 0; */
background: red;
}
.fade-leave-to {
background: black;
width: 1000px;
/* opacity:1; */
}
There is another question, I thought the leave animation should be that the DOM background becomes red firstly (while the result is it didn't or I just can't tell), then change to black slowly. So, is it my misconception?
The opacity is important because the animation is fading according to it.
Here I have added to opacity of 0 directly to the class fade-enter-active of the button Hello. You can see the animation fading step by step.
Instead, with an opacity of 1, there is no direction to your fading. It stays at 1.
I have two divs that appear like this:
The idea is that when you close the bottom div (click on the 'X'), it should disappear.
And when you close the top div, it should disappear, and also the bottom div should slide up and take its place.
I'm very new to jQuery, but this is my first attempt:
function initAnnouncements() {
$(document)
// Closes announcement modules
.on('click', 'annoucements-close', function () {
$('announcement-div').hide();
})
}
#keyframes slideInFromRight {
0% {
transform: translateX(100%);
}
.1%{
opacity: 1;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
.announcements-container {
position: fixed;
top: 80px;
right: 20px;
z-index: 1001;
display: flex;
flex-direction: column;
width: 300px;
/* align-items: flex-end; */
}
.announcements-1 {
animation: slideInFromRight 0.4s ease;
opacity: 0;
animation-fill-mode: forwards;
}
.announcements-2 {
/* animation: 0.4s ease-out 0s 1 slideInFromRight; */
animation: slideInFromRight 0.4s ease;
opacity: 0;
animation-fill-mode: forwards;
animation-delay: .4s;
margin-top: 15px;
}
.annoucements-header {
background-color: #1481C3;
color: #ffffff;
font-family: "Proxima Nova Bold";
padding: 7px 10px;
}
.annoucements-close {
position: absolute;
right: 5px;
width: 24px;
height: 36px;
cursor: pointer;
opacity: .85;
}
.annoucements-close:hover {
opacity: 1;
}
.annoucements-close::before,
.annoucements-close::after {
content: '';
width: 24px;
height: 2px;
background: white;
position: absolute;
top: 7px;
left: 0;
}
.annoucements-close::before {
transform: rotate(-45deg);
}
.annoucements-close::after {
transform: rotate(45deg);
}
/*opened or closed*/
.announcement-div-opened {
display: none;
}
.announcement-div.opened .announcement-div-opened {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="announcements-container">
<div class="announcement-div announcements-1">
<div class="annoucements-header">
<span class="annoucement-type-quantity">2 School Announcements</span>
<i class="annoucements-close"></i>
</div>
</div>
<div class="announcement-div announcements-2">
<div class="annoucements-header">
<span class="annoucement-type-quantity">1 Admin Announcement</span>
<i class="annoucements-close"></i>
</div>
</div>
</div>
</body>
As you can see this isn't doing anything. I'm trying to toggle the class from 'open' (display:block) to 'closed' (display:none) when the annoucements-close <i> element is clicked on.
And ideally I would like for the second div to slide up when the top one is closed, but first I'd just like to get either one to disappear.
What's wrong with my code where that's not working as expected?
Link to JSFiddle
There are 2 issues with your code: the click() event is inside the function initAnnouncements that doesn't get called. You could move it outside of this function or call the function. Then you have issues with your selectors: It's
.on('click', '.annoucements-close', function () {
$('.announcement-div').hide();
})
instead of
.on('click', 'annoucements-close', function () {
$('announcement-div').hide();
})
for class selectors. Working Fiddle.
If you just want to hide the annoucement which was clicked upon, just change it to
.on('click', '.annoucements-close', function () {
$(this).closest('.announcement-div').hide();
})
I looked at your code and adjusted it a little to demonstrate:
Added your common class on the two announcements "announcement-div"
Attached the document click handler with the jQuery ready event
Used the delegated event selector to listen to clicks within the document that match that common selector
On click of one of the announcement-div's animate the height to 0 and then remove the element
Comments are included in the fiddle. Hope this is helpful!
// Fire this function when the document is ready
$(function() {
// Listen on the whole document for click events on the .announcement-div element
$(document).on('click', '.annoucements-close', function () {
// From the close button find the closest parent "announcement-div"
var annoucement = $(this).closest('.announcement-div');
// Function to run after animating the element (use .hide() to keep element but display:none)
function destroy() {
annoucement.remove();
}
// Animate the annoucement's height to 0 over 400ms and then call the destroy function
annoucement.animate({ height: "0px" }, 400, destroy);
});
});
Updated JS Fiddle
.box {
width: 100px;
height: 100px;
background: red;
transition: all 1s ease-in-out;
}
.box:hover {
background: yellow;
}
<div class="box"></div>
If the cursor is over the .box for less than a second, the transition stops and falls back to it's original phase.
Is there a way to somehow force the whole animation, regardless of hover duration?
fiddle
Edit: Similar solution but relying on transition and animation: https://jsfiddle.net/ok7pnrsL/
This is my solution: https://jsfiddle.net/9yu0cozq/1/
Basically you need to add a container for the box and then play with CSS animations.
<div id="container">
<div class="box"></div>
</div>
When the mouse enters the .box then the hidden container appears (please note that for this to work that container should have enough width and height to fit the whole area where the mouse might go).
This container creates an animation for itself to "hide" back in 1s. and while it is shown the .box has an animation for the same time.
#container {
position:absolute;
z-index:1;
width: 0;
height: 0;
}
#container:hover{
animation-name:changeSize;
animation-duration: 1s;
}
#container:hover .box{
animation-name:changeColor;
animation-duration: 1s;
}
.box {
z-index:0;
position:absolute;
width: 100px;
height: 100px;
background: red;
transition:1s background;
}
.box:hover {
background: yellow;
}
#keyframes changeColor {
0% {
background: red;
}
100% {
background: yellow;
}
}
#keyframes changeSize {
0%,99% {
width: 100%;height: 100%;
}
100% {
width: 0;height: 0;
}
}
So, without knowing the real context, this solution gives a series of assumptions that might or might not fit your exact case but gives an idea of how to solve it using pure CSS.
I think you heave to use JS for this. First you need to create animation for background change, and and then you can set it as class and add that class on hover, and remove it when animation ends or on webkitAnimationEnd.
$('.box').hover(function() {
$(this).addClass('animate');
$(this).on('webkitAnimationEnd', function() {
$(this).removeClass('animate');
})
})
.box {
width: 100px;
height: 100px;
background: red;
display: inline-block;
margin: 10px;
}
.box.animate {
animation: changeColor 2s linear;
}
#keyframes changeColor {
0% {
background: red;
}
50% {
background: yellow;
}
100% {
background: red;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>
<div class="box"></div>
I don't think you can do this without javascript, but it would be interesting to find out.
A light weight javascript solution could be something like this:
// Get the elemnt
var myDiv = document.getElementById('box');
// Detect hover
myDiv.onmouseover = function() {
// Add a force class to the element
myDiv.className += " force";
// Reset the cass name after 1sec (100ms)
setTimeout(function(){ myDiv.className = "box"; }, 1000, myDiv);
}
Change your markup slightly to make things easier for now:
<div id="box" class="box"></div>
And add an extra class to your css styles along with the hover state:
.box {
width: 100px;
height: 100px;
background: red;
transition: all 1s ease-in-out;
}
.box.force,
.box:hover {
background: yellow;
}
Check the jsfiddle
I want to apply opacity: 1; to a Paragraph when hovering over itself (I have figured that out) and when I hover the header above it.
This is my CSS
.testH {
font-family: impact;
text-align: center;
font-size: 50px;
transition: all 1s;
}
.testP {
text-align: center;
opacity: 0.5;
font-size: 18px;
transition: all 1s;
}
#testHdiv:hover {
opacity: 1;
}
.testP:hover {
opacity: 1;
}
My HTML
<div id="testHdiv"><h1 class="testH"><b>< ></b></h1>
<p class="testP">Text and text, more text<br>Bla bla bla bla</p>
</div>
So, as you can see I try to get the opacity from the paragraphs current 0.5, to 1 when hovering the Div - my idea is: being able to hover a "box"/the div, and the text becomming less transparent. Though I think the opacity on the hover of the Div does not Work as the div is defined a Div, not text, and therefor can't be transparent?
I have been struggling with this for a while now. But I am basically wanting something like this: http://demo.web3canvas.com/themeforest/flathost/onepage/index.html#testimonials, where you hover within range of the text and it is being zoomed - in this case, just with opacity.
You can set a class to the <p> or just, use an operator to set the :hover to paragraph.
Example:
#testHdiv:hover > p {
opacity: 1;
}
http://jsfiddle.net/g97pusex/1/
Just change this:
#testHdiv:hover {
opacity: 1;
}
To be like that:
#testHdiv:hover p{
opacity: 1;
}
You'll want to apply the opacity to the p element, not the div. According to your provided style, you can change it to this:
.testH {
font-family: impact;
text-align: center;
font-size: 50px;
transition: all 1s;
}
.testP {
text-align: center;
opacity: 0.5;
font-size: 18px;
transition: all 1s;
}
#testHdiv:hover .testH {
opacity: 1;
}
#testHdiv:hover .testP {
opacity: 1;
}
Notice how the :hover selector is applied to the div, but the style is applied to the p element .testP
If you are trying to hover the div and on hover it affect the paragraph opacity change your CSS to:
#testHdiv:hover .testP{
opacity: 1;
}