Wednesday, April 9, 2014

CSS Cross Country Course - Level 7

Notes from Codeschool CSS Cross Country Course - Level 7

Image Replacement

Let's say you would like to use an image logo in place of a text on your website. This would be considered as part of the layout and should be in your CSS. Here we have an empty element for the anchor tag in which the logo is being added.

<!-- index.html -->
<a href="#" class="logo"></a>

/* styles.css */
.logo {
  background: url(logo.png);
  display: block;
  height: 100px;
  width: 200px;
}

This however is not best practice because if CSS is turned off, or a screen reader turned on, there is no way of telling what is there. But, if you add the text to the element, you end up with text over your logo like this:

<a href="#" class="logo">Sven's Snowshoe Emporium</a>
CSS background image with text overlay
image with unwanted text over top
To fix this issue, you can use the text-indent property on the .logo class. This will move the text out of the view port. That way we can use image replacement but still have the text telling browsers what it is.

/* styles.css */
.logo {
  background: url(logo.png);
  display: block;
  height: 100px;
  width: 200px;
  text-index: -9999px;  /* this will move the text out of the viewport */
}

Sprites

Sprites are how you create rollover effects with images. You could just add a separate image for your :hover or :visited state, but that causes slower loading. 

An example without using sprites:
<a href="#" class="logo">Sven's Snowshow Emporium</a>
CSS Example :hover
Example of using separate images
for base, and hove states

/* styles.css */
.logo {
  background: url(logo.png);
  display: block;
  height: 100px;
  width: 200px;
  text-index: -9999px;
}

.logo:hover, .logo:focus {
  background: url(hover.png)
}
Adding the hover logo separately will cause issues because the image will "flicker" when its being downloaded. This also creates another HTTP request which will slow download time for the page, especially significant for users on mobile browsers.

Instead, you can combine the images into one file, like this:
CSS Sprite Example
view of entire sprite
The total height of the new image is 200px, and the height of each individual image is 100px.  Now your :hover and :focus CSS should change to this:

.logo:hover, .logo:focus {
  background-position: 0 -100px;  /* 0 is x-axis shift, -100 is y-axis shift */
}

With this background-position applied, when you hover or focus on the image, the coordinates of the background position will shift up 100px on the y-axis, so that the second version is shown.
Example of CSS Image Sprite on hover
logo in 0, -100px background-position
Example of CSS Image Sprite
Blue logo in 0, 0 background-position


















Also of note, in our original logo declaration,

.logo {
  background: url(logo.png);
...
we didn't need to set a background position because it defaults to 0, 0 which is the correct coordinates of our default state of our logo.

Advantages of Using Sprites

- Reduces number of HTTP image requests
- Removes loading "flicker" and a need to preload images using complicated code

More examples on the web of sprites in use:
gmail and github sprites
sprites in the wild

Multiple Images and States

Here is a more complicated example of using sprites.  Here we have two icons. Each icon is 100px by 100px with a total width of 200px by 200px.
using sprites with multiple images
view of entire sprite
Here is our initial code, two anchors next to each other with a bit of space in between.
<ul class="group">
  <li><a href="#" class="twitter">Twitter</a></li>
  <li><a href="#" class="github">Github</a></li>
</ul>

li {
  float: left;
  margin-right: 10px;
}

At this point, the element displays what you'd expect:
twitter github
text before we add images

Image Replacement

First, we'll set up the shared styles for .twitter and .github.

.twitter, .github {
  background: url(social.png);
  display: block;
  height: 100px;
  width: 100px;
  text-indent: -9999px;
}

Using the background position property, you can shift the image to display the github icon in its resting state, like this:

.github {
  background-position: -100px 0;
}

image sprite as seen in viewport
twitter with bg pos at 0, 0 / github with bg pos at -100px, 0
Now add background positions for the hover and focus states:

.twitter:hover, .twitter:focus {
  background-position: 0 -100px;
}

.github:hover, .github:focus {
  background-position: -100px -100px;
}

On hover, the pixels will shift 100 pixels up to show their hover state.
CSS Image Sprite Example
dotted line signifies the part out of the viewport

Base64 Encoding

With base64 encoding you can directly embed images into your CSS, HTML, or Javascript. It is only supported by versions IE8+.  An example of a base64 encoded image looks like this:

background-image: url(data:image/png:base64, iVBO...);

Using this method with syntax like the above,  you can directly encode your images into your code, which allows you to skip using sprites or separate images. 

No comments:

Post a Comment