Different Colors Based on Position in List

Posted on: October 18th, 2011 by Lisa 1 Comment

The final change I want to make to the navigation menu, which was previously discussed in the last two posts, is to add a different color to each menu item.

Menu with different colors for border

Menu with different colors for border

On a static website which doesn’t change, this is easy. You can add a class (or an id would work also) to each item, then style each one independently.

HTML

    <ul id="nav">
      <li class="home"><a href="#">Home</a></li>
      <li class="tutorials"><a href="#">Tutorials</a></li>
      <li class="about"><a href="#">About</a></li>
      <li class="news"><a href="#">Newsletter</a></li>
      <li class="contact"><a href="#">Contact</a></li>
    </ul>

CSS

.home a { border-color: #636393; }
.tutorials a { border-color: #B5222D; }
.news a { border-color: #D4953C; }
.about a { border-color: #609491; }
.contact a { border-color: #87A248; } 

But on a dynamic site where the menus can change, such as a WordPress site, that does not work. You need a way to make the first item to be purple, the 2nd item to be red, the third item to be teal, etc.

With CSS3, there is a simple way to do this. If you use the pseudo-selector nth-child, you can specify each li item individually, then target the anchor tag inside.

li:nth-child(1) a { border-color: #636393; }
li:nth-child(2) a { border-color: #B5222D; }
li:nth-child(3) a { border-color: #D4953C; }
li:nth-child(4) a { border-color: #609491; }
li:nth-child(5) a { border-color: #87A248; }

Basically, this is saying the anchor (a) tag inside of the first li in a list, should be #636393, and then the 2nd, 3rd, 4th and 5th are also specified.

This is simple and works in the latest version of all modern browsers, including IE9! Unfortunately it does not work in IE8 and below. Many times, I am willing to let that slide, because I don’t consider the CSS3 enhancement crucial to the design. In this case, however, the color of the menu items is very important to the design and I wanted a solution that would work everywhere.

This problem can be solved by using javascript, but I wanted to see if there was a CSS only solution to my problem. I discovered a clever trick while I was searching for the answer. I really would like to credit the person who inspired this solution, but I lost the link to the blog post, so I can’t do that unfortunately.

li a { border-color: #636393; }
li+li a { border-color: #B5222D; }
li+li+li a { border-color: #D4953C; }
li+li+li+li a { border-color: #609491; }
li+li+li+li+li a{ border-color: #87A248; }

See all three solutions in the demo. (They all look the same, you need to view source to see the code differences.)

Explanation

This solution is using the Adjacent Sibling Selector. Supposedly this selector only works in IE8, but I found this solution to work just fine in IE7 also. It does not work in IE6.

The first line of the CSS will style all of the borders to the first color (#636393). The second line of CSS will take every list item is adjacent to a list item (follows it) and make them all the 2nd color. It will skip the first one, because it is not adjacent to a previous list item.

The third line will take every list item that is adjacent to a previous list item, which is also adjacent to a previous list item. This will prevent the 1st and 2nd list items from getting targeted.

Etc.

The order of the CSS is very important. In reality, the 5th list item has it’s border-color set 5 different times. Because of the cascade, the last line is the one that sets the 5th color.

Browser Support

Solution 1 will work in all browsers, but doesn’t work with a dynamic site where you are not able to specifically create class names.

Solution 2 will work in the latest version of all modern browsers, but not in earlier versions of IE.

Solution 3 works in all browsers, including IE7 and IE8. The transitions, presented in the last post, do not work in IE.

The entire navigation I’ve presented here will work horribly in IE6, so if you want to make it work there, you will need a special IE6 style sheet. I may try to do a post on that later.

/*****************************************************************************************/

Menu with Transition

Posted on: October 10th, 2011 by Lisa No Comments

In this post I am continuing the discussion of how I styled a navigation menu with transitions. The first post in the discussion is here: Vertical Navigation with a Border.

The problem I want to discuss next is how the transition caused some moving of the text, and the menu to look just a bit jumpy. I also want to demonstrate the reason you will normally add the transition properties to your normal state and not the hover state.

ul li {
	list-style: none;
	height: 44px;
}
ul li a {
	width: 100px;
	height: 40px;
	line-height: 53px;
	border-bottom: 4px solid #999;
	padding-left: 5px;
	color: #333;
	text-decoration: none;
 	display: block;
	-webkit-transition: .2s all linear;
	-moz-transition: .2s all linear;
	-o-transition: .2s all linear;
	transition: .2s all linear;
}
ul li a:hover {
	border-bottom: 35px solid #999;
	height: 9px;
}	

Explanation

The transition is added with this part of the code:
-webkit-transition: .2s all linear;
-moz-transition: .2s all linear;
-o-transition: .2s all linear;
transition: .2s all linear;

The sliding up and down of the border will take place over .2 seconds. The transition will occur on all properties that change (at least all properties that take a transition.) The easing is “linear”. Any of these values can be adjusted to personal design.

If you look at the first two menus in the demo, both have a slight shift vertically when you hover over a menu item. It appears that the transition of the border-size is not happening at exactly the same rate as the transition of the height. So the box size of the anchor tag (height + border, in this case) is not a static number.

This problem is easily solved by giving a height to the parent of the anchor tags, which in this case is the “li” tag. By setting the height to 44px, the problem is solved.

You will also notice on the demo page, on the first menu, what happens when you put your transitions on the hover state – the transition only occurs in one direction.

Browser Support

The transition will work in all of the latest versions of modern browsers, except Internet Explorer. I consider this “icing” and not necessary to the design, so I am okay with that difference. However, if you really wanted it to work in every browser, you could use javascript to make this work.

/*****************************************************************************************/

Vertical Navigation with a Border

Posted on: October 7th, 2011 by Lisa No Comments

I have been working a website with vertical navigation with some transitions and different colors on each item. The menu brought up some interesting CSS issues. I am breaking it down into smaller chunks and tackling each issue in separate posts.

I’m starting with the simplest issue and that is setting up the navigation with a small border on the bottom. The goal is to have the border grow behind the text when the user hovers.

Menu on the right showing the hover state. The border on the bottom grows to show which item user is hovering over.

ul li {
	list-style: none;
}
ul li a {
	width: 100px;
	height: 40px;
	line-height: 53px;
	border-bottom: 4px solid #999;
	padding-left: 5px;
	color: #333;
	text-decoration: none;
 	display: block;
}
ul li a:hover {
	border-bottom: 35px solid #999;
	height: 9px;
}	

Explanation

The code is similar to Horizontal Navigation, except you don’t need to float the individual list items, so it is even more simple.

The important part of the code is:
height: 40px;
line-height: 53px;
border-bottom: 4px solid #999;
padding-left: 5px;
display: block;

display: block changes the anchor tag to a block level element allowing you to give it a height. (Normally anchor tags are inline elements with no height.) The full height of the element is 44px. 40px from the height, and 4px from the border.

If I wanted the text centered in it’s box, I could have used a line-height of 40px, which is a standard technique for centering text vertically. However, I wanted the text close to the border. So I set the line-height to 53px and that centers the text on a 53px box, which ultimately places it closer to the border as I wanted. It isn’t the only solution, I could have messed around with marigns/padding, but this seemed the quickest.

The real issue is the hover state.

ul li a:hover {
	border-bottom: 35px solid #999;
	height: 9px;
}

I wanted the border to be a full 35px when hovering, so it comes up behind the text. If I didn’t change the height to be smaller, it causes a problem, similar to what I discussed in this post. However, in this case, the outline solution won’t work because I only have a border on the bottom, and outline goes on all 4 sides. See the demo, first column, for a display of the problem.

Changing the height of the box in the hover state fixes the problem. If I want to grow the border to be 35px, I need to make the height 9px, to make sure the total height remains at 44px. 9px + 35px = 44px. In the regular state: 4px + 40px = 44px. The individual numbers are not important. The important part is the TOTAL box height which = height + border + margin + padding. In my case I have no margin or padding.

In my next post, I will show how adding a transition to the border changing caused a problem and how I fixed it.

/*****************************************************************************************/

Transitions

Posted on: September 27th, 2011 by Lisa No Comments

There are two transitions happening on this site (at the moment anyway). One is in the header. When you hover over the text “CSS Snippets”, it rotates up. The rotation is actually done with the “transform” property, not “transition”. The transition part is that you can see it rotate up from the starting position to the ending position, instead of just jumping.

The other transition is when you hover over an item in the main menu. The color fades to the hover state, it doesn’t just change colors automatically.

Like many things in CSS you can specify the different parts of the transition individually, or with shorthand. I will be using shorthand unless I have a reason to not use it.

-webkit-transition: .2s all linear;
-moz-transition: .2s all linear;
-o-transition: .2s all linear;
transition: .2s all linear;		

Explanation

This is a very simple starting point for transitions. Add this snippet of code to your regular state (for example add it to the css for #navigation li a), not the hover state. If you declare your transition on the regular state, it will perform the transition in both directions, and you won’t have to account for other states like focus or active. When this code is added to the regular state of something on your page, when the hover state is activated (or your return to regular state), the changes in properties will be transitioned over .2 seconds.

The first value is the duration or the transition. The second value is what do you want to transition. “All” will make sure any property that is changed between regular state and hover state gets transitioned. You don’t need to transition all of them, however. Many different properties can use a transition, see this for a list of properties.

The last value is the timing function. For simple transitions, I find “linear” to be fine, however, there are other choices that may work better in some situations.

You can also add a delay, but it can feel weird to the user delay the transition, on simple hovers. There are interesting things you can do with it, however.

The W3C documentation can explain this property in more detail. I will have more specific examples of transitions in the future.

Browser Support

All the latest versions of the major browsers, except of course Internet Explorer, support this property. I have heard it will be supported in IE10. You do need to use the browser prefixes to make it work. If the transition must work in IE, you will have to use Javascript. Usually transitions are nice enhancements, but not necessary, so I don’t mind just using CSS.

/*****************************************************************************************/

Adding a Border to an Image on Hover

Posted on: September 1st, 2011 by Lisa No Comments

This next issue I want to cover is fairly simple, but I ran into a situation last week where I needed to find a solution to this problem, and I wasn’t sure of the best answer. I wanted to add a border on the hover state of an image. The problem is that when you add a border it adds to the width. The size of the box according to the box model is made up of width+padding+border+margin. So if you only have the border when hovering, the width of the object changes. When you have images in a grid, the problem is very obvious and actually almost nauseating to look at!

To see the problem, it will be clearest if you go to Demo page to see it in action.

A simple solution is to add a border on your image, div, etc. (wherever it is you want the border) that is the same color of your background. Obviously, this will only work if you have a solid color background. In my demo, I do, so I will add a white border initially, and change it to black on hover. That way the size never changes, but things look different on hover.

img {
  border: 3px solid white;
}
img:hover {
  border: 3px solid black;
}

To solve the problem mentioned above, you can instead use outline property. This will work when you have an image or gradient in your background. It will also work when your initial image has a border, but you want to make it larger on hover. The outline property uses the same syntax as the border shorthand.

/* Solve problem on a non-solid background */
img:hover {
  outline: 3px solid black;
} 

/* Solve problem where border size changes on hover */
img {
  border: 1px solid black;
}
img:hover {
  outline: 2px solid black;
}

Explanation

The reason this works is that outlines do not add width to your objects. They are not really in the flow of your document, so things don’t change when you hover over something. Outlines are uniform on each side. You cannot set top, right, bottom, left to be different, as you can with borders.

Notice in the second solution, where the border-size is changing, I made the outline 2px. This is so the final size of border is 3px (1+2).

Browser Support

When I first came upon this solution, I read that it did not work in IE. However, I tested in IE8 and it worked fine. It does not work in IE7. So, if hovering in IE7, the border will remain the same. It depends on the importance of the that visual effect to your design if you want to find another solution to work in IE7 or not. Another solution would be to have a 2nd image for the hover state, but that comes at a price because you are downloading more images. In most cases, I’m fine with leaving IE7 hover-borderless, but it would depend on the site and audience of course.

/*****************************************************************************************/

Text Selection Color

Posted on: August 14th, 2011 by Lisa No Comments

I have so many topics I want to cover, but very little time right now. So here is a short one on how to change the color of your selection text (when you drag your cursor over text to copy, as you would on this website!) Normally this color is a blue, but it can be changed to match your design if you want. This is not a super important detail to any web design, but it adds a nice touch.

::-moz-selection {
   background-color: #317572;
   color: #fff;
}
::selection {
    background-color: #317572;
    color: #fff;
}

Explanation

The background-color property will change your selection color, if you use ::-moz-selection for firefox, or ::selection for other browsers. It is important to also change the color property if your chosen background color won’t contrast enough. I made the color white, to contrast with my dark background color.

The idea for this came from the HTML5 Boilerplate website by Paul Irish, who chose to use a hot pink color for selecting. So if you see a website with hot pink when you drag your mouse across text, it was likely started from that boilerplate.

Browser Support

This works in all the latest versions of every browser. Even in IE9 (yeah!) It does not work in IE8 or earlier, but since this is just a nice extra design detail, and not crucial to making a website work, it is fine to add to any site.

/*****************************************************************************************/

Drop-Down Navigation with CSS only

Posted on: July 6th, 2011 by Lisa No Comments

Many drop-down navigation solutions out there rely on javascript, but it is possible to set this up with CSS only, and this is the method I prefer. This works in all browsers, with a minor change in the way things look in IE7 and below.

HTML

<body id="about">
  <div id="header">
    <ul id="nav">
      <li class="home"><a href="#">Home</a></li>
      <li class="tutorials"><a href="#">Tutorials</a>
        <ul>
          <li><a href="#">Sub Menu 1</a></li>
          <li><a href="#">Sub Menu 2</a></li>
          <li><a href="#">Sub Menu 3</a></li>
        </ul>
      </li>
      <li class="about"><a href="#">About</a></li>
      <li class="news"><a href="#">Newsletter</a>
        <ul>
          <li><a href="#">Issue 1</a></li>
          <li><a href="#">Issue 2</a></li>
          <li><a href="#">Issue 3</a></li>
        </ul>
      </li>
      <li class="contact"><a href="#">Contact</a></li>
    </ul><!-- nav -->
  </div><!-- header -->
</body>

CSS

#header {
	min-width: 800px;
	height: 150px;
}
#nav {
	width: 100%;
	background-color: #333;
	font-family:"Century Gothic", "HelveticaNeueLT Pro 45 Lt", sans-serif;
	float: left;
}
#nav li {
	list-style: none;
	float: left;
	width: 120px;
	height: 30px;
	line-height: 30px;
	text-align: center;
}
#nav li a {
	color: white;
	text-decoration: none;
	display: block;
}
#nav li a:hover {
	background-color: #066;
}
#home .home a, #home .home a:hover,
#tutorials .tutorials a, #tutorials .tutorials a:hover,
#about .about a, #about .about a:hover,
#contact .contact a, #contact .contact a:hover,
#news .news a, #news .news a:hover {
 	background-color: #FFF;
	color: #000;
	cursor: default;
}
#nav li ul {
	position: absolute;
	display: none;
}
#nav li:hover ul {
	display: block;
}
#nav li ul li {
	float: none;
	display: inline;
}
#nav li ul li a {
	width: 118px;
	position: relative;
	border-left: 1px solid black;
	border-right: 1px solid black;
	border-bottom: 1px solid black;
	background: #333;
	color: #fff;
}
#nav li ul li a:hover {
	background: #066;
	color: #000;
}

Explanation

The HTML/CSS code is built upon the Simple Horizontal Menu Navigation post. See that post for details on the basics of the navigation. This explanation will only focus on the drop-down portion of the code. The new code is in bold above.

HTML

      <li class="tutorials"><a href="#">Tutorials</a>
        <ul>
          <li><a href="#">Sub Menu 1</a></li>
          <li><a href="#">Sub Menu 2</a></li>
          <li><a href="#">Sub Menu 3</a></li>
        </ul>
      </li>

To set up the Drop Down portions of navigation in the menus, nest a second UL tag inside of the menu item’s LI tag. The code above shows this done for the Tutorials section. Nested unordered lists can be added for all the menu items if appropriate.

CSS

#nav li ul {
	position: absolute;
	display: none;
}

This hides the display of the nested navigation, so it will only show when the user hovers over the parent link. The absolute positioning allows us to determine where the drop-down menu is displayed.

#nav li:hover ul {
	display: block;
}

When the user hovers over the parent LI tag, the nested menu will now display.

The rest of the CSS is mostly for styling the menus.

Browser Support

This will work in all browsers, even Internet Explorer 6. In IE6 and IE7, however, the drop-down menus are shifted over to the right a bit. If you want the menus to look exactly the same, you will need to add some additional styling for IE7 and lower with a browser specific style sheet.

/*****************************************************************************************/

Simple Horizontal Navigation

Posted on: June 6th, 2011 by Lisa No Comments

HTML

<body id="about">
  <div id="header">
    <ul id="nav">
      <li><a href="#">Home</a></li>
      <li><a href="#">Tutorials</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Newsletter</a></li>
      <li><a href="#">Contact</a></li>
    </ul><!-- nav -->
  </div><!-- header -->
</body>

CSS

#header {
  min-width: 800px;
  height: 150px;
}
#nav {
  width: 100%;
  background-color: #333;
  font-family:"Century Gothic", "HelveticaNeueLT Pro 45 Lt", sans-serif;
  float: left;
}
#nav li {
  list-style: none;
  float: left;
  width: 120px;
  height: 30px;
  line-height: 30px;
  text-align: center;
}
#nav li a {
  color: white;
  text-decoration: none;
  display: block;
}
#nav li a:hover {
  background-color: #066;
}
#home .home a, #home .home a:hover,
#tutorials .tutorials a, #tutorials .tutorials a:hover,
#about .about a, #about .about a:hover,
#contact .contact a, #contact .contact a:hover,
#news .news a, #news .news a:hover
{
  background-color: #FFF;
  color: #000;
  cursor: default;
}

Explanation

HTML

A simple unordered list is almost always the best way to create your navigation area. It is semantic and easy to style.

<body id="about">
The purpose of adding an ID to the Body tag is so I can style the Active page differently using the body ID and class of the link (see CSS). Many people add a class like “selected” to the list item, instead of my method. However, I prefer my method, because it allows me to use the exact same HTML code for the UL/LI section on every page. I usually have a header.php file for every website and I include it on all my pages. Then if I need to modify the navigation, I only have to modify it in one place.

The DIV with an ID of “header” is not strictly necessary, but I usually have some styling on this DIV and want it for other reasons, so I am keeping it in my snippet.

CSS

#header {
  min-width: 800px;
  height: 150px;
}

I like to use a min-width to make sure if the browser window is small, the navigation won’t collapse and run to 2 lines.
#nav {
  width: 100%;
  background-color: #333;
  font-family:"Century Gothic", "HelveticaNeueLT Pro 45 Lt", sans-serif;
  float: left;
}

The float:left is to prevent the #nav area from collapsing. When children are floated, the parent can collapse, and floating the parent is one of several fixes that you can use.

#nav li {
  list-style: none;
  float: left;
  width: 120px;
  height: 30px;
  line-height: 30px;
  text-align: center;
}

list-style: none removes the bullets. float: left brings all the LI items onto one line, making it Horizontal navigation. Specifying the width is optional, and only needed if you want your navigation sections to all be the same size. Alternatively, you could add left/right padding. Making the height and line-height the same centers your text vertically.

#nav li a {
  color: white;
  text-decoration: none;
  display: block;
}

display: block allows the user to click anywhere on the full width and height of the LI item (in this case, 120px by 30px), instead of having to click on the actual word of the link. You should also style the link so it doesn’t use the default blue color for links and you can remove the underline if you want.

#nav li a:hover {
  background-color: #066;
}

You can change any number of properties that you want in the a:hover state. Here, I am just changing the background-color.

#home .home a, #home .home a:hover,
#tutorials .tutorials a, #tutorials .tutorials a:hover,
#about .about a, #about .about a:hover,
#contact .contact a, #contact .contact a:hover,
#news .news a, #news .news a:hover
{
  background-color: #FFF;
  color: #000;
  cursor: default;
}

This is where that ID on the body tag comes in handy. This allows me to style the current page with one css statement, and one UL/LI list. Besides just changing the background-color and text color, I like to make the cursor: default, so it is clear to users that nothing will change if you click on that link. It will show the arrow, instead of the hand, like on the other links.

In my next post I will be showing how to build on this navigation and add Drop-Down menus using CSS only and no Javascript.

/*****************************************************************************************/

Fix Collapsing Parents

Posted on: May 5th, 2011 by Lisa No Comments

There are many possible solutions to the problem where the parent collapses around floated elements. The following two options are the simplest fixes.

div.parent { float: left; } 

Or

div.parent div.parent { overflow: auto; }  

Make sure to change the word “parent” to the appropriate container name from your code.

A more detailed explanation of the problem and solution will be added later.

/*****************************************************************************************/

CSS Shorthand

Posted on: May 3rd, 2011 by Lisa No Comments
font: style variant weight size/line-height family;
background: color image repeat attachment position;
border: width style color;

Properties in bold are the only required values.
The order of properties is important.

Margin and Padding

There are multiple ways you can show Margins or Padding without fully specifying “margin-top”, “margin-right”, etc. You can do it all on one line with “margin” or “padding” only.

1. top right bottom left
margin: 10px 5px 15px 10px;

2. top/bottom right/left
margin: 10px 0px;

3. all the same (top/bottom right/left)
margin: 10px;

padding: (same shortcuts as margin)

The simplest way for me to remember the order of positions is to think of a clock face. Top, Right, Bottom, Left is the order of 12, 3, 6, 9 on the clock.

/*****************************************************************************************/