Overview
CSS arrows are pretty cool and have been around a little while now. I've used them in a couple of small projects and while they save me from cutting new images for arrows, the biggest benefit I think is that they allow for super fast changes in size, color, etc, without having to re-cut new images with every design iteration. That being said, I initially found it a bit difficult to grasp HOW they worked. So, here we are...
The basics
First, you need an HTML element to attach your styles to. I generally think of arrows as being almost always an inline element (i.e. flows right next to (inline with) other text), as in a toggle link to show/hide content on the page or sort links, etc. As such, I like the span tag:
I'll set a class of "arrow" on my span to use as the base setup stuff, and in this case a "right" class that I'll use to define my right arrow styling. Later on I will add classes for each arrow direction (up, down, left, right); another naming approach would be to use compass classes too if you like that (e.g. arrow-NE, arrow-S, etc).
Base CSS
I'm adding a margin to my .arrow class just to add some breathing room between my arrows in this example, but this part is not necessary for our arrows. The first thing I need to do is define my span size to 0. This is because we will be using BORDERS to define our arrows, and in order to keep a nice point, we need a 0x0 pixel box. Because inline elements don't have dimension like a block element does, we'll need to set our display to inline-block. As an alternative, you could use display: block, but then you would have to deal with floats and overflows and such. This allows us to define dimension on our span, but still keep it drawn inline. Of course, inline-block isn't well supported by IE7, so to help with that (or not, up to you), we could add *display: inline, and zoom: 1, which will allow IE7 to behave how we want:
.arrow {
margin: 5px;
height: 0;
width: 0;
display: inline-block;
/* IE7 inline-block hack */
*display: inline;
zoom: 1;
}
Adding the Arrows
Okay, now we get to the meat of things. As I mentioned earlier, we are going to be using borders to work our magic. Most often we add a single color border to our elements, so whatever border-width we have defined, the borders are drawn as a nice thick (or thin) solid border around our box. But, what happens when we define different colors for different sides of our box? Well, something like this happens:
Basically, the browser miters the corners together. All of a sudden, we start seeing the arrow shape we want, so from here it's really about defining just ONE of these arrows by using borders on only 3 sides of our box, and using a combination of color and transparency.
Now let's apply this to our "right" class. Looking again above at our grayscale box with the 4 inward pointing arrows, we want to mimic the lightest gray arrow. This is achieved by defining a colored left border, and transparent top and bottom borders. The top and bottom transparent borders are working exactly as our above example's top (black) and bottom (#666 gray) borders/arrows. In my case, I wanted to use orange and have a 25px tall arrow:
.right {
border-left: 25px solid orange;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
}
Putting it all together
Now we can build out our arrow variants. I'll start with adding several example spans with classes for each direction I want to represent:
And then add in my arrow styles:
.right {
border-left: 25px solid orange;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
}
.left {
border-right: 25px solid orange;
border-top: 25px solid transparent;
border-bottom: 25px solid transparent;
}
.down {
border-top: 25px solid orange;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
}
.up {
border-bottom: 25px solid orange;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
}
.up-left {
border-top: 25px solid red;
border-right: 25px solid transparent;
}
.up-right {
border-top: 25px solid red;
border-left: 25px solid transparent;
}
.down-left {
border-bottom: 25px solid red;
border-right: 25px solid transparent;
}
.down-right {
border-bottom: 25px solid red;
border-left: 25px solid transparent;
}
And presto - now we have nicely defined classes for each of our arrows:
Full Demo With Code
Additional Stuff
You could add a border radius if you wanted, but it would only effect the outside border edges; i.e. the "point" of the arrow will still be pointed. Still, it's a nice effect to lightly soften the outside points.
You could also add arrow tails by using :before on your arrow classes, adding content: "", giving it some dimension and color and position relative to your .arrow class (which you'd add a position: relative to set positioning context), etc...Additionally for the angled arrows (e.g. up-left, down-right), you could use CSS rotation with a 45deg (or -45deg) angles.
Finally, you could consider adding some animated rotation to your arrow direction. For example, you may have a right pointed arrow indicating an openable drawer of content, and onClick, you could add/remove your direction class to point the arrow down and animate between them. I haven't played with this yet, but it could be pretty sweet. Hooray CSS!
No comments:
Post a Comment