Forum Moderators: not2easy
I'm trying to have a block of text change to a different block of text when hovering over 4 different topics represented by images.
I'm wondering if it can be done using the "display: none" property, but it would have to link to a "hover" property of something else. I'm not even sure how to describe what I'm looking for beyond posting a link of a site that has the example.
Thanks,
Jimi
display: none; with a :hover seems a reasonable approach. Depending upon exactly what you are trying to achieve, you may need a little more.
I'm not even sure how to describe what I'm looking for beyond posting a link of a site that has the example.
You start by stripping the HTML and CSS down to the salient issue by commenting out extraneous markup unrelated to what is needed. If the solution is not found during this process, post the test ready code that replicates the problem(s) and we will look at the options from that point.
Be sure to declare a DTD and validate the markup. That will avoid, eliminate, or rule out many problems.
#1 - Validated code prevents and fixes a lot of problems. Validate your code.
W3C (X)HTML Validator [validator.w3.org]
W3C CSS Validator [jigsaw.w3.org]
The biggest issues will generally come from having to guess how large the text will render as.
Typically I'd try to have html in the shape of:
<ul id="imgmenu">
<li id="one"><a href="#">option 1 <span>explanation 1</span></a></li>
<li id="two"><a href="#">option 2 <span>explanation 2</span></a></li>
<li id="three"><a href="#">option 3 <span>explanation 3</span></a></li>
<li id="four"><a href="#">option 4 <span>explanation 4</span></a></li>
</ul>
Plugging that into a starter framework I get:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<p>BEFORE</p>
<ul id="imgmenu">
<li id="one"><a href="#">option 1 <span>explanation 1</span></a></li>
<li id="two"><a href="#">option 2 <span>explanation 2</span></a></li>
<li id="three"><a href="#">option 3 <span>explanation 3</span></a></li>
<li id="four"><a href="#">option 4 <span>explanation 4</span></a></li>
</ul>
<p>AFTER</p>
</body>
</html>
Now adding some CSS to it:
I'll need to decide where I'm goign to put the text ... as an example: I'll make it appear centered just above the images.
So I need to give the some space to it. And this is the tricky part: give too much and I end up with ugly whitespace, give too little and it'll pop all over other stuff and cause trouble. Problem with text is that users can override my font size settings ... and hence I've little control of it all.
Still to make it count for as much as I can, I'll use ems as a measure.
#imgmenu {
padding-top: 3em;
}
There some space to put the text in.
Now that menu: popping up the stuff should be close to the menu or nobody will see it happen, so let's put all the images in a centered line (any other layout for a menu will work here just as well
#imgmenu {
text-align: center;
}
#imgmenu li {
display: inline;
}
#imgmenu a {
display: inline-block;
width: 120px;
height: 120px;
}
Add a temp background the the a to see where it is ...
Of course you'll need to adapt the 120px to the size of your actual images.
Speaking of those why didn't I put them in the html ?
I'm going to use CSS sprites of course :)
So I make one larger image with the 4 images next to one another.
#one a {
background: url('sprite.jpg') no-repeat left top;
}
#two a {
background: url('sprite.jpg') no-repeat -120px top;
}
#three a {
background: url('sprite.jpg') no-repeat -240px top;
}
#four a {
background: url('sprite.jpg') no-repeat -360px top;
}
Now we need to address that text in there, first let's position the span text where it need to end up:
#imgmenu {
position: relative;
}
#imgmenu span {
position: absolute;
left: 0;
right: 0;
top: 1em;
text-decoration: none;
color: black;
}
The position:relative on the ul is to make it gain position: children (no need to be direct children) will use it as a reference in their absolute positioning.
Note if you don't want it to use this as a reference: reserve some place elsewhere on your page and position it there (remove this in that case).
I'm stretching it to make the span end up inheriting the centering I had in the menu already, but there are numerous other arrangements you might want.
If you have much text to show the space might be cramped (there's only enough space for one line right now)
Setting left and right is something IE6 will dislike: use a width in it's conditional comment if you still need to support that browser.
now we still have that text over our image ...
#imgmenu a {
display: inline-block;
width: 120px;
height: 120px;
text-indent: -9999px;
}
#imgmenu span {
text-indent: 0;
}
There it's gone for those that can see images.
All that's left is to make it hide by default and pop up on hover:
#imgmenu span {
display:none;
}
#imgmenu a:hover span {
display:block;
}
Testing it in the standards compliant browsers (ie. not IE)
show I trigger a known bug (or is it feature) in Safari (and most likely chrome as well) where the text-decoration is still on the <span> unless we also turn it off on the parent <a>.
Results in:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#imgmenu {
padding-top: 3em;
text-align: center;
position: relative;
}
#imgmenu li {
display: inline;
}
#imgmenu a {
display: inline-block;
width: 120px;
height: 120px;
text-indent: -9999px;
text-decoration: none; /* for webkit */
}
#one a {
background: url('sprite.jpg') no-repeat left top;
}
#two a {
background: url('sprite.jpg') no-repeat -120px top;
}
#three a {
background: url('sprite.jpg') no-repeat -240px top;
}
#four a {
background: url('sprite.jpg') no-repeat -360px top;
}
#imgmenu span {
position: absolute;
left: 0;
right: 0;
top: 1em;
text-indent: 0;
text-decoration: none;
color: black;
display:none;
}
#imgmenu a:hover span {
display:block;
}
</style>
</head>
<body>
<p>BEFORE</p>
<ul id="imgmenu">
<li id="one"><a href="#">option 1 <span>explanation 1</span></a></li>
<li id="two"><a href="#">option 2 <span>explanation 2</span></a></li>
<li id="three"><a href="#">option 3 <span>explanation 3</span></a></li>
<li id="four"><a href="#">option 4 <span>explanation 4</span></a></li>
</ul>
<p>AFTER</p>
</body>
</html>
Didn't check it in the different versions of IE yet.
I expect the need to fix a few things in IE6 at least. (e.g. it doesn't do setting both sides on an absolutely positioned element.)
Leaving the "fun" with IE as an exercise to the readers :)
[the bugs you trigger will differ from what your actual stuff has, so it's a bit pointless anyway]