CSS - why doesn't :hover parent hide child elements - css

I have a navigation bar with images, like so:
<ul>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
</ul>
On hovering over a list item I want to change the background color to cover the span and image like so:
.me {background-color: none;}
.me:hover {background-color: rgba(150,150,150,0.5);}
Problem is, the image does not get covered... Is this because the background is in fact... a "background" on which child elements are sitting? If so, how could I achieve this effect with plain CSS?
EDIT - solution
this worked with my original HTML structure:
<ul>
<li>
<a href="" class="ui-btn">
<span class="ui-btn-inner"> /* CONTAINS IMAGE AS BACKGROUND */
<span class="ui-btn-text">text</span> /* GETS BACKGROUND */
<span class="ui-icon"></span>
</span>
</a>
</li>
</ul>
"Negative logic": If I assign the background to list item, it sits behind all child elements, so I figured I needed to assign the background to an element that is a child of the element containing the img to have it appear above all items. span ui-btn-inner contains the image, so setting the :hover background on span ui-btn-text makes it appear above the image... weird, but works.

Yes, the background is just a background, and is placed behind any child elements.
To achieve what you're looking for, try using the css :after pseudo element to mask the image on hover:
.me {
position: relative;
}
.me:hover:after {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(150,150,150,0.5);
}
It's shiny, you get to use the image as a semantic image, and requires no extra HTML markup.

Yes, it's because the background is in fact a background. The best method to achieve this in raw css would be to continue using the background:
.me
{
background-color: none;
background-image: url(dummy.png);
background-repeat: no-repeat;
}
.me:hover
{
background-color: rgba(150,150,150,0.5);
background-image: ;
}
You could also achieve this effect with a bit of javascript as well.
<ul>
<li class="me">
<span class="cont"><img="dummy.png" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";'></span>
</li>
<li class="me">
<span class="cont"><img="dummy.png"" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";></span>
</li>
</ul>
Code not tested. It might require tweaking to get it just right.
Edit: Layering concept
None of this pseudo-code is test, but I've done it before so it may just take a bit of tweaking. I don't have a copy of the original I did on hand so I'll have to wing it. The first step is to create a relative container and 2 sub containers.
.meContainer
{
position: relative;
width: 100px;
height: 30px; /* I usually specify height/width for these things */
}
.meContainerLink
{
position: absolute;
top: 0;
left: 0; /* You need to use position to get them to overlap */
z-index: 1; /* Provide a layer */
}
.meContainerAlpha
{
position: absolute;
top: -30px; /* Move it UP 30px */
left: 0px;
z-index: 2; /* Place it on top of the other layer */
display: none; /* Hide it */
background-color: rgba(150,150,150,0.5);
}
.meContainerAlpha:hover
{
display: inline; /* Show it */
}
Then you'd need to place these in divs inside your <li>.
<ul>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
</ul>
I don't recall ever trying this method inside embedded <li> tags, so it may behave oddly at first. You may have to abandon <li> and switch to a different <div> structure entirely.

another potential option that should be more cross browser than :after could be:
.me:hover span { display: hidden; }

Related

Bootstrap - Progress bar as background in card element with anchored percentage

I'm trying to recreate something like the image below (the dark one), that looks like a progress bar in every element of a card. I'm getting close but the problem I have so far is that I can't get the percentage value anchored on the right. I think it must be outside of the bar otherwise it moves with it but I don't know how to do it.
Here's what I have so far (jsfiddle):
<div class="card" style="width: 18rem;">
<ul class="list-group list-group-flush">
<li class="list-group-item progress-bar bg-success" style="width:30%; text-align: left; padding-left: 10px;"><a>Cras justo odio<span style="float:right">30%</span></a></li>
<li class="list-group-item progress-bar bg-info" style="width:100%; text-align: left; padding-left: 10px;">Dapibus ac facilisis in<span style="float:right">100%</span></li>
</ul>
</div>
This is the goal
Simply give your .list-group-items position:relative and place the .progress inside them with position:absolute.
To place the contents of the <li> above the .progress, you'll need to wrap it inside an element and give that element position:relative; z-index: 1 (I used .content class in example below, but you might want to change it to something less general).
See it working.
Relevant CSS:
.list-group-item {
position: relative;
}
.list-group-item .progress {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 0;
}
.list-group-item .content {
position: relative;
z-index: 1;
}
You obviously need to play with the colors, but that's outside of current question's scope.

How to add delay in css image swap?

here's a little css I use to swap images. I use them for little 32px social icons which go from green image to red image. They just swap.
This is the code (using placeholder images):
.soc img:last-child {
display: none;
}
.soc:hover img:first-child {
display: none;
}
.soc:hover img:last-child {
display: inline-block;
}
<li>
<a class="soc" href="some-link-here" target="_blank">
<img src="https://lorempixel.com/32/32/cats" />
<img src="https://lorempixel.com/32/32/food" />
</a>
</li>
I want to add a little DELAY between the swaps. Like 0.8 or 1.6 seconds.. so the transition between images / color changes are smoother and prettier.
The transition should go like this: Normal Condition to HOVER condition and also, when you just hover and move mouse away, getting back to its normal condition should also have the delay.. well that's what I would love to make.
I tried all kinds of DELAY codes that I was able to google, none worked.. But I also don't want to change the main aforementioned css code which I use, to the ones that will have to have the background-image so that for each icon I gotta make a different 5 line-long css code.
Can anyone please help me with this?
Thank you.
set the right opacity starting points
:first-child or green starts at 1 or default value and goes to 0 on :hover and :first-child or red starts at 0 and goes to 1 on :hover.
position:absolute stacks the objects on top of each other.
then use transition:opacity ease 1s for the smooth animation effect. What this property does is it tells the browsers to fade the transition from opacity:0 to opacity:1 over the duration of 1s.
adding it to the selector instead of the pseudo-class :hover makes the smooth transition occur both when you hover and when you leave the :hover state.
.soc img {
position: absolute;
width: 40px;
height: 40px;
transition: opacity ease 1s;
}
.soc img:first-child {
background: green
}
.soc:hover img:first-child {
opacity: 0
}
.soc img:last-child {
opacity: 0;
background: red
}
.soc:hover img:last-child {
opacity: 1
}
<li>
<a class="soc" href="some-link-here" target="_blank">
<img src="/iconslocation/icongreen.png" />
<img src="/iconslocation/iconred.png" /></a>
</li>
It sounds you want to soften the transition between images by fading from one to the other. I recommend using CSS to transition opacity over time.
In my example below, I've positioned the second image absolutely, so it's placed directly in front of the first one, and set it to be transparent. Then I fade it in upon hover.
ul {
list-style: none;
padding: 0;
margin: 0;
}
.soc {
position: relative;
display: inline-block;
}
.soc img:last-child {
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity .2s;
}
.soc:hover img:last-child {
opacity: 1;
}
<ul>
<li>
<a class="soc" href="some-link-here" target="_blank">
<img src="//lorempixel.com/50/50/abstract/1/" />
<img src="//lorempixel.com/50/50/abstract/2/" /></a>
</li> <li>
<a class="soc" href="some-link-here" target="_blank">
<img src="//lorempixel.com/50/50/abstract/3/" />
<img src="//lorempixel.com/50/50/abstract/4/" /></a>
</li>
</ul>
Pure CSS
If we apply the default image as the background-image: url() of all a.soc elements, and give them all an :after pseudo element holding the second image to show on :hover (and optionally (and ideally for accesibility) :focus), we can then transition the opacity of the :after element to 1 on user interaction, and at full opacity it will cover/hide its parent's background-image.
The effect is as expected, but requires no <img> markup and is automatically applied by the magic of CSS to every link with class="soc".
.soc,
.soc:after {
display: inline-block;
width: 32px;
height: 32px;
background: url( https://lorempixel.com/32/32/cats );
}
.soc:after {
opacity: 0;
content: "";
position: absolute;
background: url( https://lorempixel.com/32/32/food );
transition: opacity 800ms; /* timing can be in seconds or milliseconds */
}
.soc:hover:after,
.soc:focus:after {
opacity: 1;
}
<ul>
<li><a class="soc" href="some-link-here" target="_blank"></a></li>
<li><a class="soc" href="some-other-link-here" target="_blank"></a></li>
<li><a class="soc" href="another-link-here" target="_blank"></a></li>
</ul>

issue opening jquery ui dialog inside css lightbox

I found a good lightbox effect on a blog but I'm not sure how to tweak it the way I need. Aside from manipulating background opacity and z-index, it works by setting a divs css display property to "none" and then "block" when the effect is triggered. In that div I have the unordered lists I apply the jquery menu() and dialog() methods to. The lightbox effect and the ui methods work, but the dialog won't open inside the div designated by the class: "white content". It opens behind the white content instead. I tried to change the z-index of the dialog() in my script, but it didn't work. below I have the code from my .css, .html and .js files.
CSS
/*Lightbox effect
----------------------------------*/
.black_overlay {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 2000%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 100%;
background-color: white;
z-index:1002;
overflow: auto;
}
HTML
<body>
<div id="light" class="white_content">
<div id="dialog" title="Invite">
<ul class="menu">
<li>
Age Group
<ul>
<li name="ageGroup">18-21</li>
<li name="ageGroup">21-30</li>
<li name="ageGroup">30-40</li>
<li name="ageGroup">40-50</li>
<li name="ageGroup">50-60</li>
<li name="ageGroup">60-70</li>
<li name="ageGroup">70-80</li>
<li name="ageGroup">80-90</li>
<li name="ageGroup">90-100</li>
</ul>
</li>
</ul>
<button>Button label</button>
</div>
</div>
<div id="fade" class="black_overlay"></div>
</body>
JS
$(function(){
//event handler that triggers lightbox effect
$('#list').on('click', '.edit', function(event){
//this is where the lightbox effect executes.
$("#light").css("display", "block");
$("#fade").css("display", "block");
//I want the dialog and menu to open inside of the div #light
$("#dialog").dialog();
$(".menu").menu();// closes $("menu").menu()
$( "button" ).button();
}//closes function(event)
);// closes on()
}); //closes $function.
I couldn't find a way to get a UI dialog to open inside a <div>. Might be that it is made purposely to always open as a child of <body>. In jQuery UI site the dialog runs inside a <iframe> so that might trick you to believe it's inside a <div>.
My suggestion would be to put jQuery UI components inside your lightbox as it is already kind of like a dialog. Also if you want your lightbox to move you should be good with jQuery UI's draggable and resizable.
Here's a jsFiddle I made to explain what I'm after.

CSS position <li> elements

<div class="oringal">
<ul class="rank">
<li class="rank-1">
<img src="http://netdna.webdesignerdepot.com/uploads/packaging_design/Tetra_pak_New_packaging_Juice7_by_KATOK.jpg" />
<p>1</p>
</li>
<li class="rank-2">
<img src="http://netdna.webdesignerdepot.com/uploads/packaging_design/21.jpg" />
<p>2</p>
</li>
I want to get the ranking sequence as follows, but i do not want change the html, how can i just change the css in the div.oringal to get the ranking sequence as follows.first in center, second rights, third lefts
please see the full code on jsfiddle page http://jsfiddle.net/6grsm/1/, thanks a lot
You could try using absolute positioning. It looks like you are creating a shopping cart layout so I assume that you have a fairly structured page to start with.
See demo at fiddle: http://jsfiddle.net/audetwebdesign/rC59T/
Your HTML is basically this:
<div calss="panel-wrap">
<ul class="rank">
<li class="rank-1">
<img ... />
<p>1</p>
</li>
<li class="rank-2">
<img ... />
<p>2</p>
</li>
<li class="rank-3">
<img ... />
<p>3</p>
</li>
</ul>
</div>
For the CSS:
.panel-wrap {
width: 460px;
}
The .panel-wrap is useful if you want to add background images and so on.
ul.rank {
list-style: none outside none;
padding: 0;
margin: 0;
position: relative; /* this will force the li to be positioned with respect
to this block level container */
border: 1px solid gray;
height: 200px;
}
ul.rank li {
width: 150px;
top: 0; /* pin top and bottom so that the li fills in the height
of the parent container */
bottom: 0;
border: 1px solid red;
position: absolute;
}
ul.rank img {
width: 150px;
xheight: 90px; /* Careful not to adjust both width and height which could
distort your images */
}
ul.rank p {
border: 1px dotted blue;
text-align:center;
position: absolute;
bottom: 10px;
left: 0; /* pin left and right so the p fills in the
width of the li... */
right: 0;
margin: 0;
}
The trick is to adjust the left offset for each list item in uniformly spaced increments:
.rank-3 {
top: 0;
left: 0;
}
.rank-1 {
top: 0;
left: 160px;
}
.rank-2 {
top: 0;
left: 320px;
}
The Big Advantage
What you could do is set the left offset dynamically using JavaScript/jQuery, and create an interactive page where the user can click buttons and scroll through a series of catalog items.
"i want get the sequence 3 1 2, but i do not want to change the sequence in html in div.original, my question is, how should i change the css"
From that comment, it seems that what you actually is not to change the positioning of elements, but change the order of numbering, which is a completely different question. The easiest way to do this is to use the (deprecated, but still seemingly supported) start attribute of the ol tag. In CSS, you can also set counter-increment for li tags, which will enable customisation of what the li tags display. Examples of the various methods are in this Stackoverflow answer

CSS onhover Popup

I have created CSS onHover popup as given here. but problem is, User should be able to click the Register link in the example. here, Popup disappears as I move the mouse aware form the link.
Can anyone tell how it could be achieved ?
HTML:
<div class="how f-left">
<h7>How does this work?</h7>
<div class="how-works bubble-outer">
<div class="navigation-up-arrow"></div>
<div class="body">
<h4>How It Works</h4>
<ol class="bubble-inner">
<li>Tell Us What's Wrong </li>
<li class=""> Register to Get Quotes from Local Shopshere </li>
<li class=" bold-txt ">Call Shop / Get Vehicle Serviced </li>
<li>Get Cash Back </li>
</ol>
</div>
</div>
</div>
Below CSS is used for onHover PopUp:
.how h7:hover + .how-works {
display: block;
}
You can make it display on hovering the parent (.how), not just its preceding sibling. Hovering the parent happens when you are hovering any of its descendants (the link, .how-works, any of the children of .how-works).
To do this, change:
.how h7:hover + .how-works {
display: block;
}
to:
.how:hover .how-works {
display: block;
}
DEMO
Also, if you want to make it work for touchscreens (no hover there), you could adjust a bit your HTML. Change
<h7>How does this work?</h7>
to
<a class="how-it-works" href="#" tabindex="1"><h7>How does this work?</h7></a>
and add this to the CSS as well:
.how-it-works:focus + .how-works {
display: block;
}
DEMO
Add this to your CSS:
.how-works:hover {
display: block;
}
Modified version of your demo: little link.
Here is a working example link.
Put
.how:hover .how-works {
display: block;
}
instead of
.how h7:hover + .how-works {
display: block;
}
and add position: relative; top: 0px; css properties to .how .how-works.bubble-outer{ ... }

Resources