Partial change on parent hover, full change on element hover - html

I'd like to have a UI element fade in slightly when hovering on its parent div, then fade in completely when hovering on the UI element itself. But it seems that if I set the parent hover, hovering on the child doesn't do anything.
HTML:
<div id="parent">
<div id="child">
</div> <!-- end child -->
</div> <!-- end parent -->
CSS:
#parent {
width: 200px;
height: 200px;
background-color: black;
}
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
}
/* fades in partially, looks nice */
#parent:hover #child {
opacity: 0.6;
}
/* doesn't seem to do anything! */
#child:hover {
opacity: 1;
}
JSFiddle version

The problem is that the rule #parent:hover #child has higher priority than #child:hover because it describes more elements in the DOM tree.
For increasing the priority of #child:hover there are two ways:
Describe it more precisely with
#parent #child:hover
Add !important to opacity: 1:
opacity: 1 !important;
Fiddle
#parent {
width: 200px;
height: 200px;
background-color: black;
}
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
}
#parent:hover #child {
opacity: 0.6;
}
#parent #child:hover {
opacity: 1;
}
<div id="parent">
<div id="child">
</div> <!-- end child -->
</div> <!-- end parent -->
PS: You might also want to add a transition.

It's a specificity issue. The #parent:hover #child selector is "winning out" over #child:hover. Change the second to #parent:hover #child:hover (or just #parent #child:hover), and you should be set. https://jsfiddle.net/1khjo42q/1/

Add transitions
#child {
width: 100px;
height: 100px;
background-color: white;
opacity: 0.3;
/* added these */
-webkit-transition: background-color 500ms ease-out 1s;
-moz-transition: background-color 500ms ease-out 1s;
-o-transition: background-color 500ms ease-out 1s;
transition: background-color 500ms ease-out 1s;
}

Related

Can't quite get image to scale, and use overflow:hidden to work

Here is a link to a demo
I'm not sure what I'm missing, I've done this before a few times but It's been a day of fighting this particular CSS. I want the image to enlarge, but stay within the dimensions, so a zoom effect versus any enlargement. I've attempted to move the overflow:hidden into other parent or children, but it doesn't have an effect. I've played around with the display settings as well.
Any advice? The JSfiddle link is above, and the code below. Thanks for taking a look!
#purple-square {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/purple_card.png");
border-radius: 10px;
}
#migraine-dentistry {
width: 355px;
height: 255px;
background-image: url("../img/website_cards/migraine_dentistry_card.png");
border-radius: 10px;
}
/* need position: relative in shell otherwisee the elements disappear */
#shell {
margin: auto;
width: 355px;
height: 255px;
position: relative;
transform-origin: center;
transition: 0.3s ease-in-out;
}
#shell:hover {
transform: scale(1.2);
}
#container {
width: 100%;
overflow: hidden;
display: inline-block;
transition: 0.3s;
margin: 0 auto;
}
#container div {
position: absolute;
left: 0;
transition: 0.3s ease-in-out;
}
#container:hover {
transition: ease-in-out 0.3s;
}
#container div.bottom:hover {
opacity: 0;
}
and here is the HTML setup:
<body>
<div id="shell">
<div id="container">
<div id='purple-square' class="top"></div>
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
Full working code snipped below my steps
remove unnecessary elements Removed purple square, because it's never seen in wanted animation.
Removed the part the full #container div.bottom:hover part.
Removed every style that begins with #shell in the css and later trigger the animation on #container:hover.
main issue Add an #migraine-dentistry after the #container:hover animation, so if someone hovers the container it effects the #migraine-dentistry element. (#container:hover #mi.. {trans..})
In this (#container:hov..) element remove everything and
insert transform: scale(1.2);
because we just want to scale if user is hovering.
Remove whole #container div {..} style element, because we will directly add these styles to the #migraine-dentistry element.
In #container define px values for
> width: 355px; and height: 255px;
just because we not use the #shell element anymore. Also
> set position: relative; and z-index: 2;
that the #migrain.. element is inside his parent. And
> set border-radius: 15px;
for styling. Finally
>remove the display and transition values
because they are simply not needed.
last In #migraine-de.. styles
>set width: 100%; and height: 100%;
to fit div to parent.
> remove border-radius tag
because it's set by the #container
> add transition: 0.3s ease-in-out;
to transition like you wanted.
#container {
border-radius: 15px;
width: 355px;
height: 255px;
overflow: hidden;
z-index: 2;
position: relative;
}
#container:hover #migraine-dentistry {
transform: scale(1.2);
}
#migraine-dentistry {
width: 100%;
height: 100%;
transition: 0.3s ease-in-out;
background-image: url('https://images.unsplash.com/flagged/photo-1563248101-a975e9a18cc6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80');
}
<body>
<div id="shell">
<div id="container">
<div id='migraine-dentistry' class="bottom"></div>
</div>
</div>
</body>
I know these long nights where you just can't get it done.

<div> with blur on hover to stay blurred after unhovering

I have two divs, one carrying the content, the other one existing for the sole purpose of having a background image set to blur on hover.
Both of them are placed in a single container, appear as they should, though the problem is that when I hover over the content div, logically (given the structure of the code I've written), the blur rule set to the background div is no longer active.
My question is how can I get it to work so that when I hover over the content div, the background stays blurred, or whether it is even achievable through pure HTML/CSS
.col-lg-6 {height: 100%; margin: auto; padding: 0; border: none}
.container {height: 100%; ; background: #333333; }
.content {position: absolute; z-index: 10;}
.bg {height: 100%;; background-image: url(bg.jpg);
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
-ms-transition: all 0.5s ease;
transition: all 0.5s ease;}
.bg:hover {-webkit-filter: blur(15px);}
<a href="#">
<div class="col-lg-6 col-sm-12">
<div class="container">
<div class="content">
<img src="icon.png" class="img-responsive">
<h2>Icon</h2>
</div>
<div class="bg">
</div>
</div>
</div>
</a>
You can check for the mouseover event and then set a class to the element, so it will stay with the "blurred" effect.
You can use jQuery for that, as below:
$(document).ready(function () {
$('.bg').on('mouseover', function() {
$(this).addClass('bg-hovered');
});
});
And the class:
.bg-hovered {-webkit-filter: blur(15px);}
See fiddle working: https://jsfiddle.net/guschnwg/bg03hb6k/
You need to change the :hover pseudo-class to your .container class.
Instead of this:
.bg:hover {
-webkit-filter: blur(15px);
}
Do this:
.container:hover .bg {
-webkit-filter: blur(15px);
}
This way, even if you hover the .content element, the blur will still be applied.
.container {
height: 100%;
background: #333333;
position: relative;
}
.content {
position: relative;
z-index: 10;
}
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url(http://fillmurray.com/1000/500) no-repeat center center / cover;
transition: all 0.5s ease;
}
.container:hover .bg {
-webkit-filter: blur(15px);
}
<div class="container">
<div class="content">
<img src="http://placehold.it/50x50" class="img-responsive">
<h2>Icon</h2>
</div>
<div class="bg"></div>
</div>

Absolute position div don't overlays another's div child

<div class="wrapper">
<div class="avatar"></div>
<div class="desc an-all"></div>
</div>
<div class="wrapper">
<div class="avatar"></div>
<div class="desc an-all"></div>
</div>
.wrapper{
position: relative;
width: 250px;
height: 150px;
cursor: pointer;
}
.wrapper:hover .desc{
opacity: 1;
}
.avatar{
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc{
position: absolute;
top: 50px;
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20;
}
.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
I can't figure out why is this happening. I thought that a position element inside a parent with position relative only apply inside parent and outside is a different world.
Why when I hover the green box of the first wrapper div the red one don't overlay the second's wrapper div green box ? I want the red box to be under the green one when I hover
http://codepen.io/laxmana/pen/txKbF
See if you like this example:JSFiddle
It uses your same working code, but the wrapper divs are placed within a relative parent, and each are given their own z-index. This is how you can layer one on top of another. In a real world example, the divs may not be together (like a tooltip), and then you wouldn't need the additional parent. The parent is useful when the divs are together, and on the same level. Play around with the JSFiddle, and try different options with content.
In the original example, the reason the green divs were always on top, regardless of their html order, is because the red divs are absolutely positioned, and the 2 wrapper elements are on the same level within the parent.
.wrapper {
position: relative;
width: 250px;
height: 150px;
cursor: pointer;
}
.wrapper:hover .desc {
opacity: 1;
}
.relative-container {
position:relative;
}
.top {
z-index:10;
}
.bottom {
z-index:9;
}
.avatar {
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc {
position: absolute;
top: 50px;
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20;
}
.an-all {
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
Update
Here is an example with multiple display:inline-block divs. The trick is for the z-index to work, the divs need to be siblings/on the same level as each other (this works for other elements too). The first div in the row that needs to go on top gets the highest z-index, while the last div gets the lowest z-index.
JSFiddle Example
Here is a great resource explaining the details on the z-index https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
Note: In the second JSFiddle I used display:none on the red ".desc" dropdowns, and made them visible only when moused over by adding display:block; to ".wrapper:hover .desc". In your original code even though you don't see the red divs, when you hover over their invisible area it triggers them to show. By using display:none, they are truly not displayed in the page and therefore can't trigger the hover state. The trick is that display:block overwrites the display:none in the hover class, so they will show when the green buttons are hovered over.
This hides the red divs:
.desc {
display:none;
This shows the red divs only when the green divs are hovered over:
.wrapper:hover .desc {
display:block;
Your z-index needs to change. Right now, both red boxes have an index lower than the green, which is why it appears beneath the second green box.
Update
Based on your comment, you want to have the green box both underlay the avatar class and overlay the same class below the wrapper. Because you're using classes alone, you can't have both actions. You could space the wrappers differently so you have the description still underlay the avatar and not overlap lower elements.
CSS
.wrapper{
position: relative;
width: 250px;
height: auto; /* Set this to auto to keep elements separate from one another */
cursor: pointer;
}
.wrapper:hover .desc {
opacity: 1;
}
.avatar{
width: 70px;
height: 70px;
background: green;
position: relative;
z-index: 30;
}
.desc{
position: relative; /* Keep it inside the document flow */
top:-20px; /* sets the overlap from the avatar class */
left: 0;
height: 250px;
width: 100%;
background: red;
opacity: 0;
z-index: 20; /* Displays below the avatar */
}
.an-all{
-webkit-transition: all 0.3s linear;
-moz-transition: all 0.3s linear;
transition: all 0.3s linear;
}
Working pen

How do I prevent child affected for transform scale in css3?

HTML
<div class="wrapper">
<div class="parent">
<div class="child">
lorem ipsum
</div>
</div>
</div>
CSS
.wrapper {
width: 300px;
height: 300px;
margin: 30px auto;
border: 1px dashed #ccc;
overflow:hidden;
}
.parent {
width: 1px;
height: 100px;
background-color: #f00;
opacity: 0;
margin: 0 auto;
-webkit-transition: all 0.4s ease;
transition: all 0.4s ease;
}
.wrapper:hover .parent {
opacity: 1;
-webkit-transform: scaleX(300);
transform: scaleX(300);
}
.wrapper . parent .child {
-webkit-transform: none;
transform: none;
}
I want to scale only .parent element when hovering .wrapper div. But it also affects two div (parent and child) although give transform:none property for .child div. How do I prevent .child affected?
http://jsfiddle.net/cdmkoao4/1/
Instead of transform: scaleX try changing the width
.wrapper:hover .parent {
opacity: 1;
width: 100%;
}
http://jsfiddle.net/cdmkoao4/3/
Update:
Honestly, I don't see any reason why would you use scaleX instead of width, but this is the only solution that I came up with. Simply don't nest .child with .parent, make them separate divs with position: absolute. On hover, you'd scaleX only .parent, while you'd only change the opacity of .child (I still used same classes even though they don't have parent-child status anymore).
http://jsfiddle.net/cdmkoao4/9/
You'd need to play a bit with transition-delay time to get the exact effect you want.

Change position of div on hover

Consider following HTML.
I have .image and .details wrapped in .wrap. Outside the .wrap, I have another div .extra, which I want to hide initially but on hover over the image div only, i want to slide it down so that it takes whole area of the .wrap.
I am trying following code, does not work:
HTML:
<div class="box">
<div class="wrap">
<div class="image"><img src="http://farm9.staticflickr.com/8075/8310628243_d48e64dc66_m.jpg" /></div>
<div class="details">xxx</div>
</div>
<div class="extra">hidden, show on hover over .image</div>
</div>
CSS:
.box{
border: 1px solid red;
width: 240px;
}
.image{
border: 1px solid green;
position: relative;
}
.extra{
position: absolute;
top: -100%;
left: 0;
background: green;
}
.box .image:hover .extra{
top: 0;
}
Demo: http://jsfiddle.net/pv9jd/
.extra is not a child of .image.
I updated the fiddle by replacing .image with .wrap:hover.
http://jsfiddle.net/UrKCs/2/
I'm not sure if you want that, because now the .extra appears when hovering the whole .wrap div.
I updated it again to have the hover on the image only
http://jsfiddle.net/UrKCs/5/
I believe you are looking for something like this image hover using jQuery
$('.image').hover(function(){
$('.extra').css({'top' : '0'});
},function(){
$('.extra').css({'top' : '-100%'}
);
});​
Sorry to butcher your code but this may be able to help you:
<div class="box">
<div class="image"></div>
</div>
This is the CSS:
.box div{
color: #fff;
width: 200px;
height: 100px;
position: relative;
box-sizing: border-box;
transition: border .7s ease;
}
.image{
background: #fff url(http://farm9.staticflickr.com/8075/8310628243_d48e64dc66_m.jpg) bottom;
border-top: solid 100px #ccc;
}
.image:hover{
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
border: solid 0px;
}
You can read more here for the sliding.
You can also play around here: http://codepen.io/joe/pen/oqxJu