CSS for hover to change same-level element - css

I am making a little photo gallery and I want there to be an effect on the image when you hover either the image or the text link. You can see an example here:
http://codepen.io/anon/pen/qarvc
Right now, if you hover over any of the entire parent div it triggers the hover effect I want for the image and image span. The problem though, is that if you hover over the empty space to the right of the h4 a, it still triggers the hover but the user can't actually click a link.
Now in the actual work, I have another element floated to the right of the h4 a, so it is not a solution to just make the h4 a a block.
How can I use css to target .gallery-image when h4 a is hovered?
html
<div class="galleries">
<div class="gallery">
<div class="gallery-image">
<span class=""></span>
<img src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcTEH-vPVcz7F8Yb18iLtDEjnZsbWfYG4lCFdyhKMRYax1krBnRD" alt="" />
</div>
<h4>gallery name</h4>
</div><!-- end div.gallery -->
css
#content-full {
width:960px;
padding:30px 0 0;
}
.clearboth {
clear:both;
height:0;
}
.gallery {
position:relative;
float:left;
width:300px;
margin:0 10px 35px;
}
.gallery-image span {
background:url("http://inventionhome.com/wp-content/uploads/2014/07/zoom.png") no-repeat center center;
width:90px;
height:90px;
display:none;
z-index:999;
margin:auto;
position:absolute;
top:-50px; left:0; bottom:0; right:0;
}
.gallery-image {
background-color:#4576a4;
}
.gallery-image:hover span, .gallery:hover .gallery-image span {
display:block;
}
.gallery-image img {
display:block;
width:100%;
height:230px;
-webkit-transition: all 200ms ease-out;
-moz-transition: all 200ms ease-out;
-o-transition: all 200ms ease-out;
transition: all 200ms ease-out;
}
.gallery-image:hover img, .gallery:hover .gallery-image img {
opacity:0.2;
}
.galleries h4 {
margin-top:5px;
line-height:27px;
}
.galleries h4 a {
color:#142533;
}
.galleries h4 a:hover {
text-decoration:none;
}

The issue you are running into with using only CSS is that there doesn't exist a CSS selector to select the previous or parent element. You can work around this stipulation if your images are going to be consistent sizes (height), you could put the <h4> ahead of the <div class="gallery-image"> and position it below the image with position: absolute; -- allowing your to use the CSS ~ selector to have hover events affect the image because it is after the element in the DOM. Also, I alleviated your white space selector issue with display: inline-block;:
<div class="gallery">
<h4>...</h4>
<div class="gallery-image">...</div>
</div>
.gallery {
position:relative;
}
.gallery-image:hover span {
display:block;
}
.gallery-image:hover img {
opacity:0.2;
}
.galleries h4 {
margin-top:5px;
line-height:27px;
display: inline-block;
position: absolute;
top: 230px;
}
.galleries h4:hover~.gallery-image img {
opacity:0.2;
}
.galleries h4:hover~.gallery-image span {
display: block;
}
-- I only included edited CSS above
JSFIDDLE

I'm bringing another answer, the symbol "+" also works when it comes to apply a style to an element of the same level in markup hierarchy :
The CSS modified :
.galleries h4:hover + .gallery-image img {
opacity:0.2;
}
.galleries h4:hover + .gallery-image span {
display: block;
}
It works only if the element we are targeting is immediatly positionned after the initial. In our case it works, just after h4:hover, we find .gallery-image.

Related

Can't Increase :active duration in CSS

I'm trying to increase the duration of CSS :active and found this thread How to increase the duration of :active in css? I tried this but it didn't work on my code.
here my code:
li {
transition:0s 1s;
}
li:active:before {
content:"hello !";
z-index:99999999;
position:fixed;
bottom:0px;
width:100%;
background:black;
text-align:center;
color:white;
padding:10px 0;
transition:0s;
}
<li>Style This</li>
the :active rule will stop matching as soon as the mouse button is released. thus the :before will be removed.
You could render the block, and not display it until the :active starts matching.
caveat: If the :before block is clicked, its parent will also become active.
In the end, I would opt for a JavaScript solution.
li {
transition:0s 1s;
}
li:before{
content:"hello !";
z-index:99999999;
position:fixed;
bottom:0px;
width:100%;
background:black;
text-align:center;
color:white;
padding:10px 0;
transition:1s;
opacity:0;
}
li:active:before {
display:block;
opacity:1;
transition:0s;
}
<li>Style This</li>
The trick won't work as you expect simply because there is no transition applied to the li element.
You need first to understand how it works. Here is a simple example:
.box {
background:red;
height:200px;
transition:0s 1s;
}
.box:active {
background:green;
transition:0s;
]
<div class="box"></div>
When you click, the active state is considered; thus the transition is set to 0s and the background become immediately green. When you release the mouse, the active state is no more considered and we have the new transition with a dely so the the background go back to red after this delay.
So in order to have such think, you may consider doing the same but with the pseudo element:
li:before {
content: "hello !";
z-index: 99999999;
position: fixed;
bottom: 0px;
width: 100%;
background: black;
text-align: center;
color: white;
padding: 10px 0;
opacity:0;
transition: 0s 4s;
}
li:active::before{
opacity:1;
transition: 0s;
}
<li>Style This</li>
I considred opacity but it can work with any animatable property.

Ripple Effect Buttons CSS3

Here is a code from W3Schools on how to create a ripple effect button.
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
}
.button:after {
content: "";
background: #f1f1f1;
display: block;
position: absolute;
padding-top: 300%;
padding-left: 50%;
margin-left: -20px !important;
margin-top: -120%;
opacity: 0;
transition: all 15s;
}
.button:active:after {
padding: 0;
margin: 0;
opacity: 1;
transition: 0s;
}
Can someone help me understand the code bit by bit, especially why the padding and margin in the button:after are so highly set and how the zero values in the button:active:after affect the animation?
Any help will be highly appreciated. (I know the basic of padding and margin, but I think that I am not getting the 'after' class and the technique used).
:after is not a class is a pseudo-element that it's used to add content to the content of an element .see here ::after
so it uses that pseudo-element to create a new space with CSS that it's not defined in your initial HTML . it's like making another element inside the button
for eg if you had a structure like this :
.no_pseudo, .with_pseudo {
width:100px;
height:100px;
background:red;
margin:40px 0
}
.likeAfter {
background:blue;
width:50%;
margin:0 auto;
height:100%;}
.with_pseudo {
position:relative;
}
.with_pseudo:after {
content:"";
position:absolute;
background:blue;
width:50%;
margin:0 auto;
height:100%;
lefT:0;
right:0;}
<div class="no_pseudo">
<div class="likeAfter">
</div>
</div>
<div class="with_pseudo">
</div>
as you can see, the :after element can be used just like a child element inside a div. but you can achieve that just by using CSS .you don't have to change the HTML structure.
so this trick is using :after , which has a background: #f1f1f1; and it's positioned under the button ( margin-top:-120% ) . and then, when you click on the button , it has (margin:0 ) that's how this effect is done
also with paddings and opacity.
i would've done it differently :
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
z-index:2;
}
.button:after {
content: "pseudo element >!<";
color:green;
background: #f1f1f1;
display: block;
position: absolute;
bottom:0;
left:0;
height:0%;
width:0%;
opacity: 0;
transition: all 3s;
}
.button:focus:after {
width:50%;
height:100%;
opacity: 1;
}
<button class="button">
I AM A BUTTON
</button>
i positioned the :after at the bottom-left of the button , with width:0%;height:0%;opacity:0 ;
then, when i click on the button, i added width:50%;height:100%;opacity:1 on the :after and that's how you get that effect . maybe is not exactly the same as in your example but it works.
also added some content:"" to the :after element. you can add text,images etc. almost anything. but if you don't want to add anything, you must use content:"" and leave it empty, otherwise the :after is not created.
:before is the same as after > see here more about pseudo elements
css_pseudo_elements or here Pseudo-elements
there is much to talk about this things, but i hope you kind of understood what's going on with the pseudo-elements and with this effect. let me know. cheers !
EDIT AFTER COMMENT :
1. ' transition backwards ' is because of the :active state ( :active ) . the button has the :active state only when you click on it . after that it's not active anymore and :after goes back to it's original style
and because it has transition:15s it takes 15 sec to get back to it's original position and color.
the same with the ripple effect. you click on the button, the effects starts , :after gets from one style to another , for example from opacity:0 to opacity:1 then because the button doesn't have :active state anymore, :after returns to it's original style of opacity:0 , all this happens in 15 seconds ( because of the transition:15s )
2
content:"" inserts the space for the :after or :before into the HTML structure
you need content:"" on :after because , as i said in the beginning ,
::after is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is
key word content . so even if you don't insert text or images but you just want to insert an empty space , you need to set up a content:"" which means empty but still there .
elem:after{content:""} generates a space with width:0;height:0 after the element.
i will make two short examples , one with something inside content:"" one with nothing inside it
h1:before {
content:"i am before < < < ";
font-size:14px;
color:red;
}
h1:after {
content:" > > > i am after";
font-size:14px;
color:blue;
}
h2:before {
content:"";
background:red;
width:20px;
height:20px;
position:absolute;
}
h2:after {
content:"";
background:blue;
width:20px;
height:20px;
position:absolute;
}
<h1>Text Before me </h1>
<h2>Just empty content </h2>

Show div and hide another on hover with transition

I have searched other questions but none are giving the result I am looking for.
I am trying to :hover in order to show another div and also hide another div at the same time. I can't wrap all divs in one parent div, because then the div I want to hide being :hover over will trigger the show/hide... and in addition do it with a nice transition.
Only when hovering over the 'hover me' text should the show/hide trigger.
The .remove_me class and text 'make me disappear' isn't disappearing on :hover. That is what I am unable to achieve.
Fiddle
CSS
.hover_me {
cursor:pointer;
-webkit-transition: .4s;
transition: .4s;
display:block;
height:30px;
background:#ccc;
width:70px;
line-height:30px;
text-align:center;
}
.show_me {
display:none;
}
.hover_me:hover + .remove_me {
display:none;
}
.hover_me:hover + .show_me {
display:block;
}
.remove_me {
display:block;
HTML
<div class="hover_me">hover me</div>
<div class="show_me">show me</div>
<div class="remove_me">make me disappear</div>
This for example is not what I want to happen: http://jsfiddle.net/MBLZx/ the show/hide should only be triggered by the 'hover me' text
It should work as you want it to if you do it like this:
I changed your CSS code
.hover_me:hover + .remove_me {
display:none;
}
To:
//Note the tilde
.hover_me:hover ~ .remove_me {
display:none;
}
Explanation on the tilde
Hope this helps
I have changed your selector, and changed the display (that can not be animated) to opacity (that can)
.hover_me {
cursor:pointer;
-webkit-transition: .4s;
transition: .4s;
display:block;
height:30px;
background:red;
width:70px;
line-height:30px;
text-align:center;
}
.show_me {
opacity: 0;
}
.hover_me:hover ~ .remove_me {
opacity: 0;
}
.hover_me:hover + .show_me {
opacity: 1;
}
.remove_me {
margin-top: -1em;
opacity: 1;
}
div {
transition: opacity 1s;
}
<div class="hover_me">hover me</div>
<div class="show_me">show me</div>
<div class="remove_me">make me disappear</div>
Actually to select the remove_me you have to apply the one more + as show_me lies in between. + select the next tag class. so we have to put the + .show_me on between
.hover_me:hover + .show_me + .remove_me {
display:none;
}
check the fiddle http://jsfiddle.net/stdeepak22/enmxx59b/
You need to ...
use the general adjacent selector ~ and not the direct adjacent selector + to make .remove_me "disappear"
use opacity or any other property that you can use with transition (not display) to create a show/hide effect
Change your CSS as follows:
.hover_me:hover ~ .remove_me{
display:none;
}
Demo fiddle here
.hover_me {
cursor:pointer;
-webkit-transition: .4s;
transition: .4s;
display:block;
height:30px;
background:red;
width:70px;
line-height:30px;
text-align:center;
}
.show_me {
opacity: 0;
}
.hover_me:hover ~ .remove_me {
opacity: 0;
}
.hover_me:hover ~ .show_me {
opacity: 1;
}
.remove_me {
opacity: 1;
}
.toggled{
position: absolute;
transition: opacity 300ms;
}
<div class="hover_me">hover me</div>
<div class="toggled show_me">show me</div>
<div class="toggled remove_me">make me disappear</div>

CSS3 arrow hyperlink

Trying to make arrow link with CSS.
This one works in Firefox, but has a problems in IE and webkit-based browsers with arrowhead's position. Double div used for centering link content. Any suggestions?
content
<a href="#" class="readmore">
<div>
<div>
link content
</div>
</div>
</a>
content
CSS
.readmore {
text-decoration:none;
}
.readmore > div {
display: table;
height: 30px;
//width: 100%;
background: #008a00;
transition: background 0.2s;
}
.readmore > div:hover {
background:orange;
}
.readmore > div::after {
content:"";
display:inline;
position:absolute;
border: 15px solid;
margin-top:-15px;
border-color:transparent transparent transparent #008a00;
transition: border-left-color 0.2s;
}
.readmore > div::before {
content:"";
display:inline-block;
width:6px;
position: static;
background:#008a00;
transition: background 0.2s;
}
.readmore > div:hover::after {
border-left-color:orange;
}
.readmore > div > div {
display: table-cell;
//text-align: center;
vertical-align: middle;
color:white;
}
You should set the top explicitly to 0 for the :after element, and also remember to set the position:relative for the div element so that the absolute positioning works as expected:
.readmore > div::after {
...
top:0;
}
.readmore > div {
...
position:relative;
}
Fiddle
NOTE: The negative margin-top should be removed. The cause of your problem is you use negative margin-top (maybe by trial and error until it looks OK in FF), but the position also depends on the top and left. The default values of these properties are implemented differently by different browsers, the only solution to set it in order is explicitly set the top, left and remember the rule to determine the containing block for the absolute positioned element. (the nearest ancestor which has position as absolute or relative).
Try this code -- >
HTML :
<div>content</div>
Link
<div>content</div>
CSS :
a{
padding:10px;
background:#2ecc71;
display:inline-block;
position:relative;
}
a:hover{
background:orange;
}
a:hover:after{
border-left: 20px solid orange;
}
a:after {
display: inline-block;
content: "";
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 20px solid #2ecc71;
position: absolute;
right:-20px;
top:0;
}
JS FIDDLE DEMO
The border width and the right and top positions can be tweaked according to your needs

CSS div that appears when hovering on anchor; keeping it visible while hovering over div

I have a div that I want to pop up when I hover over the link before it. The hover works great, but there is a link inside the div that appears that I want people to be able to click but it disappears when I try to go to it.
Here is the jsfiddle
I am trying to use just CSS here but if I need any jquery or anything then cool.
#soldoutinfo a {
padding:4px 2px;
font-size:10px;
}
#soldoutinfo, .soldout {
display:inline;
}
#soldoutinfo a {
color:#cc0000;
}
#soldoutinfo a:visited {
color:#cc0000;
}
#soldoutinfo + div {
display:none;
width:0;
height:0;
position:absolute;
}
#soldoutinfo:hover + div {
display:block;
height:60px;
width:250px;
background:#ffffff;
box-shadow: 0 0 4px #888888;
position: absolute;
padding: 8px;
top: 19px;
left:12px;
z-index:1000;
}
#soldoutinfo + div p {
font-size:12px;
}
<p id="soldoutinfo">
<sup><a>?</a></sup>
</p>
<div>
<p>Hope is not lost! Send us a message and we will see if our stores have any in stock to ship to you.
</p>
</div>
The problem is that the hover effect is on the element after the anchor. So when you leave the anchor, your hover effect will end to.
You could fix it like this, although it's not the cleanest solution:
Set your tooltip inside your anchor, using a span
<p id="soldoutinfo">
<sup><a>?</a></sup>
<span>Hope is not lost! Send us a message and we will see if our stores have any in stock to ship to you.</span>
</p>
#soldoutinfo span {
display:none;
width:0;
height:0;
position:absolute;
}
#soldoutinfo:hover span {
display:block;
height:60px;
width:250px;
background:#ffffff;
box-shadow: 0 0 4px #888888;
position: absolute;
padding: 8px;
top: 19px;
left:12px;
z-index:1000;
}
JSFiddle DEMO
Edited your fiddle:
http://jsfiddle.net/s8QWY/6/
See if this works for you. Basically what I did was this:
Make the hidden div be inside the div that you have to hover over to get it to show.
Make the position of the parent div relative
Make the position of the shown div be over where the hovered element so that the div still shows when you hover over the div itself.
<div id="soldoutinfo"><sup><a>?</a><div><p>Hope is not lost! Send us a message and we will see if our stores have any in stock to ship to you.</p></div></sup></div>
#soldoutinfo a {
padding:4px 2px;
font-size:10px;
}
#soldoutinfo, .soldout {
display:inline;
position: relative;
}
#soldoutinfo a {
color:#cc0000;
}
#soldoutinfo a:visited {
color:#cc0000;
}
#soldoutinfo div {
display:none;
width:0;
height:0;
position:absolute;
}
#soldoutinfo:hover div,
#soldoutinfo div:hover {
display:block;
height:60px;
width:250px;
background:#ffffff;
box-shadow: 0 0 4px #888888;
position: absolute;
padding: 8px;
top: 3px;
left:3px;
z-index:1000;
}
#soldoutinfo + div p {
font-size:12px;
}
Here a approach point:
When you hover the ?
$("#id").hover(function(){
$(this).find("#toShow").show();
}
and when he leaves the #toShow
$('#toShow').mouseout(function() {
$('#toShow').hide();
});
I see no JS code in this fiddle I don't know why. But solution to you would be to use setTimeout(); in this function you can specify after what period of time after hover the box should be hidden. You can also add to hide() param 'slow'.
You can also use ready solution which is Jquery UI ToolTip

Resources