Changing properties of one div element when hovering above other div elements - css

Sorry to bring this up again since I am quite sure it was answered in threads like here, yet posting in older threads appears to be pointless. But I'd like to know whether this is still true that I will in fact need jQuery (or something similar) in order to change the properties of one div-element when hovering above some other div-element?
If the answer would still be yes, please have a look at the following picture:
This is part of my navigation I am trying to bring to life right now. As you can see there is some kind of mirror effect underneath the buttons. I want those buttons to be clickable while having a "hover" background-position / background-image change. I tried to do that with a single div-element which didn't work out since the button-area itself is smaller than the entire graphic so even when I was hovering above the reflection the button was ready to be used which was not very intuitive.
Currently I am using a div-element to display the background image including the hover effect and - sorry but I don't really know how to describe the following - some kind of "invisible" text link which is forced to a specific size in order to simulate a clickable area. Here a small visualization:
Green is the area of the background image which is changing upon hovering above the div-element and the red area is the "button".
So again the question ... do I still need something like jQuery to get this hover effect working only when I hover above the button area, are there different approaches to this or ... is something like jQuery really the only answer to that?

I've got a quick solution that is working in Firefox 3.6, you can try it at jsFiddle.
It is not exactly the answer to your question, but offers a solution to your design.
HTML:
<div id="container">
<a href="target1.html" id="button1">
<div id="reflection1-active"></div>
</a>
<div id="reflection1-inactive"></div>
</div>
CSS:
#container{
position: relative;
}
#button1{
background-color: #900;
height: 32px;
width: 80px;
display: block;
position: absolute;
z-index: 10;
}
#button1:hover{
background-color: #F00;
}
#button1 #reflection1-active{
position: absolute;
background-color: #f77;
height: 32px;
width: 80px;
display: block;
top: 32px;
display: none;
}
#button1:hover #reflection1-active{
display: block;
}
#button1 #reflection1-active:hover{
display: none;
}
#reflection1-inactive{
background-color: #977;
height: 32px;
width: 80px;
top: 32px;
display: block;
position: absolute;
z-index: 0;
}

when you hover on an element (link/button) inside another element (parent div) you are actually still hovering on the parent element too so you can effect the two of them at the same time:
HTML:
<div>the button</div>
CSS:
div {width: 100px; height: 200px; background: green;}
a {display: block; height: 100px; background: #000;}
div:hover {background: #cfc;}
a:hover {background: #eee;}
If I'm understanding the question right, the background (green to lightgreen) changes no matter if you're on the "button area" or not (div:hover), whereas the button area only changes when you're on the button itself as it's effected by only the a:hover
[Update]
actually I think I have misunderstood the question: you want to change the background image of the div only when you hover the <a> (button)?
put the new full background on the <a> and have it change it's height too it will mean a bigger "button" area, but that will only be when the button is actually hovered on anyway
try this CSS instead:
div {width: 100px; height: 200px; background: green;}
a {display: block; height: 100px; background: #eee;}
a:hover {background: #000; height: 200px;}

I don't know whether any browsers support this, and I've never tried, but... Could you use a selector for a sibling adjacent to the hovered element, and then use the adjacent element to render the shadow? Since the adjacent element is not a child of the hoverable element, hovering over that would not trigger the hover selection match.

Related

Why is absolutely positioned element still in hover scope even though it is visually detached from parent area?

I have a simple question over CSS's relative-absolute relationship.
Here's simple example.
HTML:
<div class="relative">
relative area
<div class="absolute">I am relative area's son. Hover over me! my bg-color changes!</div>
</div>
CSS:
.absolute {
width: 140px;
height: 140px;
background-color:tomato;
position: absolute;
left: 120%;
top: 0;
}
.relative {
position: relative;
border: 2px solid #000;
width: 200px;
height: 200px;
margin-top: 200px;
}
.relative:hover .absolute {
background-color: yellowgreen;
}
https://codepen.io/nori2tae/pen/ZXgMjZ
When I hover over .absolute its background color changes.
This shows that though it is visually detached from parent area(.relative), as long as a child element(.absolute) semantically belongs to its parent, browser thinks mouse pointer is also on .absolute, right?
Therefore hover over .absolute also means .relative:hover?
And is this so called hoisting?
Someone pls clear the fog over my head.
It might be "visually" detached but to the browser DOM parser still sees your page a bunch of HTML tag. Since the CSS did not change the DOM model the Browser still thinks the absolutely positioned element is still inside its parent element.
Now since browser is responsible for handle such mouse events you get the mentioned behavior.
Its called trickling or capturing.. (different terms for the same thing)
Hoisting is a different concept in javascript (Eg. function and variable declarations are moved to the top during compilation
.relative:hover .absolute {
background-color: yellowgreen;
}
I understand your css like so: When hover on .relative, make its child .absolute change background. And it does just that (because .absolute is the child of .relative). I don't see what's wrong here?
The reason you hover over .absolute and still get the background change is because in fact you're hovering over .relative.

Box creation in CSS

I have an unordered list as a menu and the current item has a class active. I want the the active item to have a little box below it like in the image attached. How would I do this using just CSS? If there is no (good) answer I will go old-school and create an image as a background-image.
What you're describing can be done using a pseudo-element and positioning it relative to the element you're decorating: http://jsfiddle.net/fC7gn/
.box {
position: relative;
}
.box:after {
content: '';
position: absolute;
top: 100%;
width: 100%;
height: 10px;
background-color: blue;
}
You can add the following to your CSS:
a:hover{border-bottom:10px solid red;}
You can add the border-bottom style to any element. I attach it to the a tag so it spans the entire width of the content it contains.
Here's an example fiddle (don't mind the extra fluff)

Rendering Raphael elements upon paper with opacity

I am using Raphael 2.1.0 (raphaeljs.com) with no problem. Actually I'm drawing elements upon a <div> with opacity: 0.6;. It is obvious that the Raphael elements get the same opacity.
I was wondering if there was any way to render opaque elements (100%) upon a transparent paper (60%).
Here is a JSFiddle to illustrate my thing.
What I thought at first was putting a layer without background right above my transparent <div>, which would be my paper. That way, it could give its opacity (100%) to my Raphael elements.
But I'm thinking I am missing an easier way.
From your fiddle, I can see that you have an outer div called #overlay and a div inside that called #paper. You are rendering your paper inside #paper and applying background:white; opacity:0.6; style to #paper itself.
As mentioned in comments in your question, using background-color: rgba(255,255,255,0.6); instead of opacity is an option. But that will not work IE 8 and below and alos on some older versions of other browsers.
A much more semantic way to do it would be to insert a new div with same height as the #paper before #paper and then apply a negative margin to #paper to bring it above the newly inserted div.
<div id="overlay">
<div id="paperbg"></div>
<div id="paper"></div>
</div>
And your CSS would go like
#overlay {
background: #88bb00;
height: 400px;
padding: 10px;
width: 200px;
}
#paper {
height: 400px;
width: 200px;
margin-top: -400px;
}
#paperbg {
width: 200px;
height: 400px;
background: white;
filter: alpha(opacity=60);
opacity: 0.6;
}
Updated Fiddle: http://jsfiddle.net/shamasis/AFTQV/8/

align icons with text

What's the best way to align icons (left) and text (right) or the opposite text on left and icon on right?
Does the icon image and text have to be the same size? Ideally I would like them to be different but be on the same vertical alignment.
I am using background-position css property to get the icons from a larger image.
Here is how I do it now, but I am struggling with either getting them to be on the same line or be vertically aligned to the bottom.
Text
This is what I get after I try your suggestions.
Though the text is now aligned with the icon, it is superimposed over the icon to the right of the icon that I want. Please note that i am using the background position to show the icon from a larger set of images.
Basically I am getting
<icon><10px><text_and_unwanted_icon_to_the_right_under_it>
<span class="group3_drops_icon group3_l_icon" style="">50</span>
group3_drops_icon {
background-position:-50px -111px;
}
.group3_l_icon {
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background:transparent url(/images/group3.png) no-repeat scroll left center;
height:35px;
overflow:hidden;
padding-left:55px;
}
I usually use background:
<style type="text/css">
.icon {
background-image: url(path/to/my/icon.jpg);
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px; /* Or size of icon + spacing */
}
</style>
<span class="icon">Some text here</span>
You can do it on the same line using vertical-align and line-height
<p style='line-height: 30px'>
<img src='icon.gif' style='vertical-align: middle' />Icon Text
</p>
Alternatively, you can go the background approach with no-repeat and positioning:
span.icontext {
background: transparent url(icon.gif) no-repeat inherit left center;
padding-left: 10px /* at least the width of the icon */
}
<span class="icontext">
Icon Text
</span>
Sadly, neither of these answers are bullet proof and each have one big flaw.
#rossipedia
I used to implement all my icons this way and it works quite well. But, and this is a big but, it does not work with sprites, since you're using the background-position property to position the icon inside the container that includes your text.
And not using sprites where you can is bad for performance and SEO, making them imperative for any good modern website.
#Jamie Wong
The first solution has two markup flaws. Using elements semantically correctly is sadly underrated by some, but you'll see the benefits in prioritizing form in your search engine ranking. So first of all, you shouldn't use a p-tag when the content is not a paragraph. Use span instead. Secondly, the img-tag is meant for content only. In very specific cases, you might have to ignore this rule, but this isn't one of them.
My Solution:
I won't lie to you, I've checked in a lot of places in my time and IMHO there is no optimal solution. These two solutions are the ones that come closest to that, though:
Inline-Block Solution
HTML:
<div class="container">
<div class="icon"></div>
<span class="content">Hello</span>
</div>
CSS:
.container {
margin-top: 50px;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
display: inline-block;
vertical-align: middle;
}
.container .content {
display: inline-block;
vertical-align: middle;
}
"display:inline-block;" is a beautiful thing. You can do so much with it and it plays very nicely with responsive design.
But it depends on your client. Inline-Block does not work well with IE6, IE7 and still causes problems with IE8. I personally no longer support IE6 and 7, but IE8 is still out there. If your client really needs his website to be usable in IE8, inline-block is sadly no option. Assess this first. Replace the black background of the icon-element with your sprite, position it, throw no-repeat in there and voilĂ , there you have it.
Oh yeah, and as a plus, you can align the text any way you want with vertical-align.
P.S.: I am aware that there's an empty HTML-tag in there, if anyone has a suggestion as to how to fill it, I'd be thankful.
Fixed Height Solution
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
.container {
margin-top: 50px;
border: 1px solid #000;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
float:left;
}
.container .content {
line-height: 30px;
float: left;
display: block;
}
I hate this one. It uses a fixed line height for the text, and if you choose the same height as the Icon's box, the text is centered to that height. To align the text to the top, cut the line height, and as to the bottom, you'll have to fix that with position: absolute and a fixed width and height for the container. I'm not going to get into that unless someone requests it, because it's a whole issue for itself, and brings with it a lot of disadvantages.
The main disadvantage of this path is the fixed height. Fixed heights are always unflexible and especially with text, it can cause a bunch of problems (You can no longer scale the text as a user without it being cut off, plus different browsers render text differently). So be sure that in no browser the text is cut off and that it has some wiggle room inside its line height.
P.S.: Don't forget the clearfix for the container. And, of course, replace the black background with your sprite and according position + no-repeat.
Conclusion
Use inline-block if at all possible. ;) If it's not, breath deeply and try the second solution.

How to place text at the bottom when there's predefined height!

This should be incredibly trivial, but it's not. I have a predefined height for an anchor, and I would like to place the text at the bottom.
<li><a class="my-text">My Text</a></li>
I used the following CSS, which does not work. The text still appears at the top.
a.my-text {
background-color:#cccc;
height:50px;
vertical-align:bottom;
width:100px;
}
The idea is: I want to align text to the bottom, but if there is text that is longer than one line, I want the over flow to go to the top, not push everything else down... any ideas of how this could be achieved?
This can't be done using css and the html you provide. If you put an extra span in the anchor, it can be done:
a.my-text {
height: 50px;
display: block;
}
a.my-text span {
position: absolute;
bottom: 0;
}
You can use bottom:0px with position:absolute in anchor.
HTML
<li><a class="my-text">My Text</a></li>
CSS
li {
position: relative;
height:200px;
border: 1px solid red;
}
a.my-text {
bottom: 0px;
border: 1px solid blue;
position: absolute;
background-color:#cccc;
width:100px;
height:50px;
}
See in jsfiddle.
It definitely would not work, because <a> anchors are inline tags, therefore assigning them heights and widths is useless. The vertical-align property determines the positioning of inline elements with respect to the line they're in, not the vertical position of the text. (See http://reference.sitepoint.com/css/vertical-align) As far as I understand what you are requesting cannot be done. However, there are alternatives, as suggested above, to achieve similar effects.
The issue with your code is that the anchor won't respond to height/width because it is an inline element. If you you add a {display: block} to the anchor it's now a block element, but, as I recall, vertical-align doesn't work on the contents of block elements. This was the easiest way I could think of using display: table-cell.
a.my-text {
background-color: #ccc;
height: 200px; width: 100px;
vertical-align: bottom;
display: table-cell;
}
It sounds like you just need to get rid of the height rule on the anchor tag and use something like padding-top: 45px on the li

Resources