How to create menu like on the picture? CSS style - html

How to create menu like on the picture?
For now I have:
<div id="nav">
<nav class="top-nav">
<div class="shell">
HOMEPAGE<span></span>
<span class="top-nav-shadow"></span>
<ul>
<li class="active"><span>home</span></li>
<li><span>services</span></li>
<li><span>projects</span></li>
<li><span>solutions</span></li>
<li><span>jobs</span></li>
<li><span>blog</span></li>
<li><span>contacts</span></li>
</ul>
</div>
</nav>
</div>
And my css for div nav:
#nav{
background-color: transparent;
padding: 0em 0em 0em 2em;
white-space: nowrap;
list-style: none outside none;
margin: 0px;
height: auto;
line-height: normal;
}
How to style this? I'm newbie

From your picture i think you are looking for a way to make Tabs not a menu..
The best thing you can use i think is jQuery Tabs
From that link you can check how to make it using simple html and the jQueryUI css.
If you want to use only css and html kindly check this
How to make a simple tabbed menu with CSS and HTML

I created an example.
Please have a look at it.
Working Fiddle
The main concept this is positioning the li tags on ul.
Giving bottom: -1px to the li tags to let them come on the border of the ul.
If you give li border-bottom then it looks like border of ul.
I hope you can create your own styling by referring this (but not copying the code).

Here's a jsFiddle showing the styles you want.
The LI tags are floated left, and overflow: hidden; is set on the parent UL tag to contain the floats.
The entire UL tag is shifted down position: relative; margin-bottom: -1px; over the top of the element below it. The 1 pixel borders under the A tags give the illusion that the tab is part of the element below. The border-bottom-color on the active tab is set to match the background color of the content area.
The A tags are set as display: block; so that they can be given a min-width, text-align: center; and vertical padding
I also put a small border-radius on the A tags for flair :-p This can be removed if you don't want it.
I'm assuming the class .active will be changed by code running on your server. If not, the JS listed in several of the above answers will change the class when a tab is clicked. Some of the answers only change the class on the tab (which isn't really what you want…), so look at the libraries instead (however, the CSS will need to be modified accordingly as most JS tab libraries require a specific HTML structure). If you need further details, please leave a comment below.

You'll need a few js to do it.
Here is an example which doesn't require any framework, and fit to your needs (using jQuery) :
$('#tab-nav > li').click(function(e) {
// get new active pane id
var idPane = $(this).find('a:first').attr('href').substring(1);
// change active nav
$('#tab-nav > li').removeClass('active');
$(this).addClass('active');
// change active pane
$('.tab-pane').removeClass('active');
$('#'+idPane).addClass('active');
});
.clear { display: block; clear: both; height: 0px; }
#container {
position: relative;
color: #497188;
}
#tab-nav {
position: relative;
z-index: 20;
}
#tab-nav > li {
display: block;
border: 1px solid #497188;
border-bottom: 1px solid #497188;
padding: 1px 3px;
margin: 0 2px -1px;
float: left;
}
#tab-nav > li a {
color: #497188;
text-decoration: none;
}
#tab-nav > li.active,
#tab-content {
background: #DEE7EC;
border-bottom: 1px solid #DEE7EC;
}
#tab-content {
position: relative;
clear: both;
border: 1px solid #497188;
z-index: 10;
}
.tab-pane {
display: none;
position: absolute;
top: 0;
left: 0;
padding: 3px;
}
.tab-pane.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="container">
<ul id="tab-nav">
<li class="active"><span>home</span></li>
<li><span>services</span></li>
<li><span>projects</span></li>
<li><span>solutions</span></li>
<li><span>jobs</span></li>
<li><span>blog</span></li>
<li><span>contacts</span></li>
</ul>
<div id="tab-content">
<div id="home" class="tab-pane active">home</div>
<div id="services" class="tab-pane">services</div>
<div id="projects" class="tab-pane">projects</div>
<div id="solutions" class="tab-pane">solutions</div>
<div id="jobs" class="tab-pane">jobs</div>
<div id="blog" class="tab-pane">blog</div>
<div id="contacts" class="tab-pane">contacts</div>
<p class="clear"> </p>
</div>
</div>

Related

Margin above and to the left and right of the header containing the navbar despite setting margin:0 explicitly

Navbar component-
body {
margin-top: 0;
padding: 0;
font-size: 18px;
}
.container {
width: 95%;
margin: 0 auto;
}
header {
margin-top: 0;
background: blue;
padding: 1em;
}
a {
color: white;
text-decoration: none;
}
a.logo {
font-weight: bold;
}
nav {
float: right;
}
ul {
list-style-type: none;
margin: 0;
display: flex;
}
li:hover {
filter: brightness(50%);
}
li a {
padding: 1em;
}
<header class="head">
<div class="container">
Home
<nav>
<ul>
<li> hello</li>
<li> whatsup</li>
</ul>
</nav>
</div>
</header>
<div class="container">
<router-outlet></router-outlet>
</div>
I am using chrome I notice a thin white strip of space at the top and the left and the right of the header component containing the navbar. How can i remove this such that the white space is replaced by navbar color ie. blue.
I am new at css, and Would be good if an explanantion of the cause could be provided.
Thanks
body {
display: block;
margin: 8px;
margin-top: 8px;
margin-right: 8px;
margin-bottom: 8px;
margin-left: 8px;
}
Added the css that displays on the inspect element for further clarity
I changed the margin-top:0 with the margin:0 for the body.
I hope it would work.
body {
margin: 0;
padding:0;
font-size: 18px;
}
Styling inline for body was one workaround that worked incase the browser doesnt recognize body css(assuming there wasnt any errors in the css ofcourse) and applies default styling.
From the update in your question where you show us the CSS being applied, as seen in the element inspector, we can see that your CSS is not being picked up by the browser at all.
Its difficult to tell why, but here are a few things that can help you fix it:
If it is in an external CSS file, check that the file is being included
Check for typos in the CSS for the body
Check for typos or misplaced } in any CSS before the body CSS - an error in preceding CSS could prevent the rest of the CSS in that file from being applied
Try adding that CSS directly into the HTML in a style tag to see if it works there... if so:
Try deleting the CSS and retyping it manually - Very occasionally I've seen issues where code copied from the internet or elsewhere can have hidden characters that cause problems.

How do I make my hamburger menu appear directly under my hamburger icon?

I want to have to click on a hamburger menu icon and then have the list display beneath my icon. I set up my hamburger menu icon with this style
.menu-btn div {
position: absolute;
left: 100%;
top: 64%;
padding-right: 8px;
margin-top: -0.50em;
line-height: 1.2;
font-size: 18px;
font-weight: 200;
vertical-align: middle;
z-index: 99;
}
.menu-btn span {
display: block;
width: 20px;
height: 2px;
margin: 4px 0;
background: #989da1;
z-index: 99;
}
The menu of options taht should appear after you click on the hamburger menu is
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
but I'm unclear how to set up the style of the hamburger menu so taht it appears directly under the hamburger menu when you click on it. Right now, its appearing centered at the top of the screen -- https://jsfiddle.net/wtp1k57b/1/ . How do I set up such a style?
PS - I'm looking for a solution that doesn't rely on hard-coding numeric (e.g. top: 27px) pixel values. Certainly its good to get things to work in my little Fiddle, but in my broader application I can't guarantee how big or small that hamburger menu will be.
I would like to show a completely different approach without using display: flex.
HTML
Your approach uses too many wrappers in my opinion. You can definitely reduce the amount of divs. Moreover, you should always try to use semantic tags over general tags like div or ul. Consider looking at this article.
Hence, as #scooterlord already mentioned, you should use a button for the hamburger icon. Moreover, I recommend to use a nav instead of a list.
CSS
First of all, you should bundle the attributes for the same selector at the same place for the purpose of improved clarity. You should not have three sections where you apply the universal selector, but combine it into one. Moreover, do not set the box-sizing to a specific value, but rather set it to inherit, so you can always override this value for a specific element without having to do it for all of its children. Furthermore, I do not understand what you want to achieve with margin: 0 auto on all elements and body. It does not make any sense for me.
Since you do not want to use absolute positioning, I would strongly advise you to avoid using pixels as a measuring unit. They behave badly if some people change their default font-size because of poor eyesight or other reasons. Instead, consider to apply relative units like rem, em or %. By setting the root element's font-size to 62.5% you are still able to calculate as if you were using pixels (1rem = 10px).
As I already mentioned, I avoided to use display: flex for such a trivial thing. I do not understand why it should be used at this point. Therefore, I also had to change the positioning of the menu button. The navigation could be easily positioned using percentages for top and left.
As a side note: You should really try to only post the relevant CSS code - the first step for me was to remove all the irrelevant parts of it.
Final Solution
This is my final solution without Flexbox, without fixed sizes and without absolute positioning using px:
$('.menu-btn').click(function() {
$('nav').toggleClass('nav-open');
});
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%;
}
body {
font: 1.6rem/1.4 Benton Sans, -apple-system, BlinkMacSystemFont, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
header {
width: 100%;
background-color: orange;
text-align: center;
padding: 1rem;
position: relative;
}
nav {
display: none;
width: 30rem;
padding: 5rem;
background-color: #ededed;
position: absolute;
right: 5%;
top: 100%;
}
.nav-open {
display: block;
}
nav a {
display: block;
width: 100%;
text-align: center;
padding: 1.4rem 1.6rem;
text-decoration: none;
cursor: pointer;
font-size: 2.2rem;
color: #000;
}
nav a:hover {
background-color: #111;
color: #fff;
}
.menu-btn {
position: absolute;
right: 5%;
top: 50%;
margin-top: -1.1rem;
display: inline-block;
cursor: pointer;
border: none;
outline: none;
background-color: transparent;
}
#media only screen and (min-width: 500px) {
.menu-btn, nav {
display: none !important;
}
}
.menu-btn span {
display: block;
width: 2rem;
height: 0.2rem;
margin: 0.4rem 0;
background: #989da1;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<h2>Page Title</h2>
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<nav>
Vote
Search
About
Log In
</nav>
</header>
Or see this fiddle.
Use the css properties: top and right to set the position of the element under your icon.
#menu
{
position: absolute;
top: 48px;
right: 2px;
background: #ededed;
list-style-type: none;
}
Use this CSS for your menu - no margin, and the position defined by the top and right settings:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 50px;
right: 0;
}
https://jsfiddle.net/meuexde6/
I left out the transition for the testing, but you should basically animate the right parameter from -100px to 0 to achieve what you seemed to have in mind.
ADDITION AFTER COMMENT:
To define the position of the menu in relation to the button, you have to apply position: relative to their common parent element, .mobile-nav. The position values of an element with position: absolute always relate to the first ancestor which has position: relative.
I changed the values in my updated fiddle accordingly to these:
#menu {
position: absolute;
width: 300px;
margin: 0;
padding: 50px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
top: 40px;
right: -32px;
}
Updated fiddle: https://jsfiddle.net/meuexde6/1/
If you really want the menu to stick directly to the button (hard to say - it has no borders), just adjust the top and right values as needed.
HTML5 Semantic Elements.
details > summary {
padding: 2px 6px;
width:12px;
border: none;
list-style: none;
}
details > summary::-webkit-details-marker {
display: none;
}
ul{
list-style: none;
margin-left:0;
padding-left:0;
}
<details>
<summary>☰</summary>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</details>
So, here goes. I know you are asking for a solution to a specific problem, I solved it alright, but I couldn't help noticing that you are struggling with your code. You must simplify the way you think and your code will become leaner. The purpose of this forum is to help others become better, right? :)
HTML
It is good practice to keep the menu toggle button OUTSIDE of the menu - will solve a lot of issues - check below.
It is not semantically right to use anything else rather than a button for the toggle function, so, why not use a button here? I also removed unnecessary clutter from your code, like some divs and the id - the id could be traded with the class, your call. I also removed .mobile-nav because it is not needed at all.
<button class="menu-btn">
<span></span>
<span></span>
<span></span>
</button>
<div class="responsive-menu">
<ul id="menu">
<li>Vote</li>
<li>Search</li>
<li>About</li>
<li>Log In</li>
</ul>
</div>
CSS
I absolutely positioned the menu-btn on the top right corner, and gave it a width equal to the #pageTitle height (which I set at 50px - a gold standard) to keep it rectangular; it should be a rule of thumb that the toggle buttons are rectangular and always the same height as the top navigation bar - in this case the before-mentioned id. The same I did for the .responsive-menu. I absolutely positioned it as shown below. The changes allowed me to remove a lot of css styling - now obsolete - like for example the absolute positioning of the ul menu inside the .responsive-menu.
.menu-btn {
position:absolute;
display:block;
right:0;
top:0;
width:50px;
height:50px;
background:yellow;
border:none;
padding:16px;
}
.responsive-menu {
position: absolute;
top: 50px;
right: 0;
display: none;
}
Javascript
By years of practice I realized that the most efficient way to toggle a menu instead of adding and removing classes is to add a class on the body tag; this can help heaps if you want to restyle anything else on the page depending on wether your menu is opened or not.
$('.menu-btn').on('click', function() {
$('body').toggleClass('responsive-menu-open');
});
Here is a working jsfiddle: https://jsfiddle.net/scooterlord/4atafhge/
I could have done a lot of other things in order to simplify the code even further - remove unnecessary ids and classes since most elements are considered unique and could be targeted using descendant classes, eg .responsive-menu ul, etc. After a lot of practice, you'll manage to think simpler and produce code with a smaller footprint.
Edit: Concerning the fact that you don't like the absolute pixels for alignment here is a trick.
Giving a fixed height to the parent container, equal to the toggle button's -in this case '#pageTitle' and setting its position to relative allows you to use top:100% to properly place the responsive menu exactly below the button (which is essentially the same height):
#pageTitle {
display: flex;
height: 50px;
position:relative;
}
.responsive-menu {
position: absolute;
top: 100%;
right: 0;
display: none;
}
Here is an updated fiddle: https://jsfiddle.net/scooterlord/4atafhge/1/
Edit: Natalia, I gave it some thought and here is what I came up with. I created an absolutely positioned .menu-wrapper, inside of which I placed the button and the responsive menu with float:right and no positioning - aka they are positioned statically. No more pixel values! YAY!
.menu-wrapper {
position:absolute;
top:0;
right:0;
}
.menu-btn {
float:right;
...
}
.responsive-menu {
float:right;
clear:both; // to clear the .menu-btn and sit exactly below it
...
}
Here is a working fiddle: https://jsfiddle.net/scooterlord/4atafhge/2/

Positioning div relative (absolute) to a fixed navbar

I have a fixed navbar at the top of my page, and want to position an element below it, relative to how big the navbar is. When resizing the browser window, my navbar will jump into 2 or 3 lines from one, and I want my div (.articles-showcase) to move accordingly.
I tried achieving this by nesting my div inside the navbar container and using position: absolute;, top: 0;, but this just always positions my div at the top of the page.
Is there a way to do this using css, or should I look for a javascript solution?
I am currently using bootstrap and angular JS and wouldn't like to add jQuery to my project if not necessary.
Here's my html:
<div class="header" ng-controller="NavbarController">
<ul>
<li ng-class="{ active: isActive('/PTC-Testers') }">PTC-Testers</li><li ng-class="{ active: isActive('/articles') }">articles</li><li ng-class="{ active: isActive('/sites') }">PTC sites</li><li ng-class="{ active: isActive('/account_reviews') }">account reviews</li><li ng-class="{ active: isActive('/forum') }">forum</li><li ng-class="{ active: isActive('/contact') }">contact us</li><li ng-class="{ active: isActive('/login') }">login</li>
</ul>
<div class="articles-showcase">
<div class="col-xs-6 col-md-3">
<p>featured</p>
<h1>What I learned while cooking</h1>
<h3>author | posted </h3>
</div>
<div class="col-xs-6 col-md-3">
<p>most read</p>
<h1>My favorite things about dogs</h1>
<h3>author | posted </h3>
</div>
<div class="col-xs-6 col-md-3">
<p>highest rating</p>
<h1>It's finally friday people!</h1>
<h3>author | posted </h3>
</div>
<div class="col-xs-6 col-md-3">
<p>featured track</p>
<h1>starting your own adventure</h1>
<h3>author | posted </h3>
</div>
</div>
</div>
the relevant part of my CSS:
.header {
background-color: red;
color: #fff;
border-bottom: 0.3em solid cyan;
position: fixed;
top: 0;
z-index: 10;
width: 100%;
}
.header ul {
list-style: none;
text-align: center;
margin: 0;
padding: 0;
}
.header ul li {
display: inline-block;
}
.header ul li a {
font-family: 'Ubuntu', sans-serif;
font-weight: 400;
font-size: 1.3em;
color: #fff;
padding: 5px 1em;
margin: 0;
display: inline-block;
text-decoration: none;
outline: none;
}
.header ul li:hover {
background-color: #ff6666;
text-decoration: none;
}
.header ul .active {
background-color: cyan;
}
.articles-showcase {
position: absolute;
top: 0;
z-index: 11;
border-bottom: 0.2em solid cyan;
padding: 0.5em;
width: 100%;
}
.articles-showcase div {
text-align: center;
}
.articles-showcase div h1, .articles-showcase div h3, .articles-showcase div p {
margin: 0;
padding: 0.3em;
color: #660000;
}
.articles-showcase div p {
font-size: 1.2em;
color: red;
}
.articles-showcase div h1 {
font-size: 1.7em;
}
.articles-showcase div h3 {
font-size: 1.4em;
}
Based on the anwser from #Milos Miskone Sretin I came up with this crude jQuery solution:
$(window).resize(function() {
$('.articles-showcase').css('top', $('.header ul').outerHeight());
});
I still need to test this in different browsers and on mobile devices but for now, it seems to do the trick.
If anyone can come up with a css alternative to do this (maybe something including bootstrap classes that I do not know about), please let me know.
If you want to put div below fixed element you can do it by setting its top margin to height of navbar.
But, in your case, because you don't have fixed height it is not that simple. You need to use javascript to achieve this.
The simplest way is to use jQuery, if I am right, you already have it loaded since you are using bootstrap. Try in this way:
$(document).ready(function() {
$('.articles-showcase').css('top', $('.header').outerHeight());
});
Also, I am not completely clear. Is both .articles-showcase and ul under header div. If you want to put .articles-showcase under ul do it like:
$(document).ready(function() {
$('.articles-showcase').css('top', $('.header ul').outerHeight());
});
You can do it without jQuery but using jQuery is an easiest way.
Hope this can help you.

grouping CSS elements

I'm having a real hard time wrapping my brain around grouping different selectors and styles into one coherent setup.
I found this one set of CSS/HTML code that is exactly what I need (http://jsfiddle.net/joshnh/daFDn/) but I'm at a loss how I can utilize it with my setup.
body {
padding: 50px;
}
ul {
border: 1px solid #444;
display: inline-block;
height: 301px;
position: relative;
width: 400px;
}
li {
font: bold 16px/100px sans-serif;
height: 100px;
}
a {
border-right: 1px solid #444;
border-top: 1px solid #444;
color: red;
display: block;
text-align: center;
text-decoration: none;
width: 99px;
}
li:first-child a {
border-top: none;
}
li:nth-child(2) a {
color: blue;
}
li:nth-child(3) a {
color: green;
}
a:hover {
background: red;
color: #fff;
}
li:nth-child(2) a:hover {
background: blue;
color: #fff;
}
li:nth-child(3) a:hover {
background: green;
color: #fff;
}
img {
background: red;
display: none;
height: 301px;
position: absolute;
right: 0;
top: 0;
width: 300px;
}
li:nth-child(2) img {
background: blue;
}
li:nth-child(3) img {
background: green;
}
a:hover + img,
img:hover {
display: block;
}
I have a WordPress site, using Headway Themes (GUI theme creator). I want to create a section on one page that does exactly what the Fiddle does. I also don't want any other similar HTML elements to be affected by the CSS in that fiddle. (i.e. I use LI's elsewhere on the site and don't want them "font: bold 16px/100px sans-serif;" like this example).
For me, this truly baffles my mind and would seriously appreciate some guidance on how to structure this correctly.
I'm sure I need to create an ID (because this page will be unique to the rest of the site) but I'm not sure that this is correct syntax for an ID:
#switch ul {border: 1px solid #444;display: inline-block;height: 301px; position: relative;width: 400px;}, li {font: bold 16px/100px sans-serif;height: 100px;}
(as an example but is essentially what I want to do)
Just had a quick stab at this - As you say, you'll need to add something to limit those selectors to the scope you're interested in. An id is one way of doing this - in that case you would need to update your selectors to look something like: http://jsfiddle.net/2osg7a31/
Two things to look out for:
- ul#switch instead of #switch ul (since you're applying the styles to the ul that has an id of #switch, rather than a ul with a descendant of #switch)
- Make sure all styles for the descendants are limited to the #switch id too, not just those applied directly to the ul tag.
I'd suggest using a class instead of an id might be a better idea, since you're only adding the identifier to allow styling, rather than to try and identify the element uniquely: http://jsfiddle.net/0h54wseL/
Yes, you'll need to use and id or preferably a class which is better if you want to repeat that specific fiddle in other pages of your website. The way to do it is to add a .switch in every css entry for the list style. Then in your HTML put the whole ul inside a div with class="switch".
HTML:
<div class="switch">
<ul>
<li>
Item 1
<img src="" alt=""/>
</li>
<li>
Item 2
<img src="" alt=""/>
</li>
<li>
Item 3
<img src="" alt=""/>
</li>
</ul>
</div>
Here is the fiddle to explain : http://jsfiddle.net/zyd1822w/1/
Also check this link for more info about essential css selectors.
I hope this helps.

Building overlapping, oddly-rotated sprites

My current project involves setting up a bunch of sidebar links, such that the finished design looks like this:
The envelopes are supposed to move and overlap (i.e., change z-index), depending upon which icon/text is currently has :hover state.
I thought each would be a separate PNG file, but I've been given a sprite that looks like this:
Any suggestions how I could achieve this? Normally I'd just change the background position of the list elements each piece of text is in, but I don't think this is possible given the overlapping nature of these. Does he just need to export it differently?
Many thanks...
To me it looks like that sprite would work perfectly. The left most image is for when book is hovered, second image for twitter, third for facebook, forth for email. I'm guessing the last one is just the default state. Its tricky to make this work with pure css and :hover (but possible!), however, it would be extremely easy with javascript.
For the pure css solution, the div with the sprite would have to be the child of all the text elements, so you could change the background based on :hover on the parent (the text). If this isn't clear, I can make you some example code.
Edit:
Its not perfect, but its a proof of concept.
JsFiddle: http://jsfiddle.net/jp6fy/
CSS:
#side{
position:relitive;
height:341px;
width:250px;
}
#link1{
top:0;
}
.link{
position:absolute;
left:0;
top:85px;
height:85px;
padding-left:160px;
width:90px;
}
#image{
position:absolute;
top:-255px;
left:0;
z-index:-1;
background:url(http://i.stack.imgur.com/I2Y4k.png) -720px 0;
height:341px;
width:150px;
}
#link1:hover #image{
background-position:-540px 0;
}
#link2:hover #image{
background-position:-360px 0;
}
#link3:hover #image{
background-position:-180px 0;
}
#link4:hover #image{
background-position:-0px 0;
}
HTML:
<div id='side'>
<div class='link' id='link1'>
email
<div class='link' id='link2'>
facebook
<div class='link' id='link3'>
twitter
<div class='link' id='link4'>
book
<div id='image'></div>
</div>
</div>
</div>
</div>
</div>
It is possible. (But ugly.)
As a :hover selector can only affect elements inside (or directly adjacent) to the triggering element, the solution is to nest the trigger elements: (jsFiddle)
<style>
div {
width: 100px;
height: 100px;
position: absolute;
left: 100px;
}
#image { background: black; }
#trigger1, #trigger1:hover #image { background: red; }
#trigger2, #trigger2:hover #image { background: green; }
#trigger3, #trigger3:hover #image { background: blue; }
</style>
<div id="trigger1">
<div id="trigger2">
<div id="trigger3">
<div id="image"></div>
</div>
</div>
</div>
But preferably, you'd get the envelope sprites exported separately (you can of course still use CSS sprites). That should give you simpler HTML and CSS, a smaller image, and you'll avoid having to muck around with nested absolutely positioned elements, each having its own coordinate system.
I tried an approach which keeps the markup fairly simple, with only one extra non-semantic div per item:
<ul>
<li id="email">
<div class="background"></div>
<em>Email</em> chris
</li>
<li id="facebook">
<div class="background"></div>
<em>Facebook</em> follow us
</li>
<li id="twitter">
<div class="background"></div>
<em>Twitter</em> your life away
</li>
<li id="book">
<div class="background">
</div><em>Book</em> a project
</li>
</ul>
I positioned all the different copies of the background div at the same place, then varied the background position based on the hover states:
/* First, just style the document and the list text in general.
skip on for the important bit */
body {
background-color: black;
color: white;
}
ul {
width: 350px;
margin-top: 40px;
position: relative;
}
li {
margin-right: 40px;
font-family: "Century Gothic", Helvetica, sans-serif;
text-align: right;
margin-bottom: 0px;
padding: 15px 4px 25px 0;
}
li em {
text-transform: uppercase;
display: block;
}
li:hover {
color: red;
}
/* From here down is the important bit */
/* Set up the sprite in all the .background divs */
div.background {
background-image: url(http://i.stack.imgur.com/I2Y4k.png);
position: absolute;
top: 0;
left: 0;
height: 341px;
width: 160px;
}
/* By default, turn off the background in all the divs */
div.background {
display: none;
}
/* Just picking an arbitrary item to show the default, non-hover background */
#email div.background {
display: block;
background-position-x: -737px;
}
/* If we're hovering over the list as a whole, disable the default background,
so it doesn't show up underneath the background we want to display */
ul:hover #email div.background {
display: none;
}
/* For the email item, which shows our arbitrary default background, override
to the email background on hover with more specificity than the default rule */
ul:hover #email:hover div.background {
display: block;
background-position-x: 0px;
}
/* For all other items, override to their background on hover */
#facebook:hover div.background {
display: block;
background-position-x: -375px;
}
#twitter:hover div.background {
display: block;
background-position-x: -189px;
}
#book:hover div.background {
display: block;
background-position-x: -556px;
}
Working, though slightly rough example, in this jsFiddle.
Note that it's okay to have multiple copies of the sprite in multiple different divs; the browser will just grab one copy for its cache and use that for all instances of the image.
Could you create an image map and then hover swaps the image to the one with the correct envelope in front. See this link on an interesting link
google search link on idea
My method with clean HTML.
.nav { position: relative; }
.nav li {
margin-left: 179.8px;
list-style-type: none;
}
.nav li:before {
position: absolute;
left: 0; top: 0;
content: url(http://i.stack.imgur.com/I2Y4k.png);
clip: rect(0 899px 341px 719.2px);
margin-left: -719.2px;
z-index: 1;
}
.nav li:hover:before { z-index: 2; }
.email:hover:before {
clip: rect(0 179.8px 341px 0);
margin-left: 0;
}
.facebook:hover:before {
clip: rect(0 359.6px 341px 179.8px);
margin-left: -179.8px;
}
.twitter:hover:before {
clip: rect(0 539.4px 341px 359.6px);
margin-left: -359.6px;
}
.book:hover:before {
clip: rect(0 719.2px 341px 539.4px);
margin-left: -539.4px;
}
<ul class="nav">
<li class="email">Email</li>
<li class="facebook">Facebook</li>
<li class="twitter">Twitter</li>
<li class="book">Book</li>
</ul>