Skewed menu buttons with css transform

With the help of css-transform, it is quite easy to create skewed menu buttons. They look cool, are easy to build and for older browsers you will still get functional, non-skewed menu buttons.

Let's just start with html and css code for a basic menu:


<ul class="menu">
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">Item 3</a></li>
    <li><a href="#">Item 4</a></li>
    <li><a href="#">Item 5</a></li>
</ul>

.menu {
	list-style-type: none;
	margin: 0;
	padding: 0 5px;
}
.menu li {
	background-color: #000000;
	border-radius: 5px;
	display: block;
	float: left;
	margin: 0 5px 0 0;
	padding: 0;
}
.menu li:hover {
	background-color: #666666;
}
.menu a {
	border-radius: inherit;
	color: #FFFFFF;
	display: block;
	padding: 5px 15px;
}

The next step is to use the css transform property. Transform has many possibilities, but for this example we will only use the skew function. The skew function can skew elements both along the x-axis and along the y-axis. And again, this is a simple example, so we will only skew the menu buttons along the x-axis, like this. And we currently need vendor prefixes, like for many CSS3 properties.


.menu li {
	-moz-transform: skewx(20deg);
	-ms-transform: skewx(20deg);
	-o-transform: skewx(20deg);
	-webkit-transform: skewx(20deg);
	transform: skewx(20deg);
}

For the sake of completeness, here is the syntax for skewing along the x-axis, y-axis and both axis' at the same time. NB! Remember vendor prefixes like used above.


.menu li {
	transform: skewx(xdeg);
	transform: skewy(ydeg);
	transform: skew(xdeg,ydeg);
}

Now that we have skewed the menu buttons, the text was also skewed and we don't want that. So the text needs to be skewed back.


.menu a{
	-moz-transform: skewx(-20deg);
	-ms-transform: skewx(-20deg);
	-o-transform: skewx(-20deg);
	-webkit-transform: skewx(-20deg);
	transform: skewx(-20deg);
}

There. Problem solved. Just a slight little problem that most people won't notice anyway, but the links no longer covers 100% of the menu buttons. The upper left and lower right corners are not clickable and a small area outside the lower left and upper right corners is clickable.

I have no better ideas for this than to insert a dummy span element inside the links so only the text and not the actual link area is skewed back. Perhaps it can be done in some way with :after and :before pseudo elements but I have not been able to figure out how.


<ul class="menu">
    <li><a href="#"><span class="dummy">Item 1</span></a></li>
    <li><a href="#"><span class="dummy">Item 2</span></a></li>
    <li><a href="#"><span class="dummy">Item 3</span></a></li>
    <li><a href="#"><span class="dummy">Item 4</span></a></li>
    <li><a href="#"><span class="dummy">Item 5</span></a></li>
</ul>

.menu a {
	-moz-transform: none;
	-ms-transform: none;
	-o-transform: none;
	-webkit-transform: none;
	transform: none;
}
.menu a .dummy {
	-moz-transform: skewx(-20deg);
	-ms-transform: skewx(-20deg);
	-o-transform: skewx(-20deg);
	-webkit-transform: skewx(-20deg);
	transform: skewx(-20deg);
}

Now I am not a big fan of inserting html code just for providing CSS hooks and the problem we solve in this last step is pretty insignificant. So I would probably leave the last step out in a real world project.

The complete example page

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>