jasonkarldavis.com

example sample

CSS Slants

A trick I recently learned about is the "border slant" (referenced from now on as a slant). I was surfing the net and stumbled upon to this: http://www.infimum.dk/HTML/slantinfo.html. I had seen Eric Meyer's Slantastic Demo before, but it didn't quite click at the time. I'm not going to bother explaining slants, as the first link does a better job that I probably could.

Anyway, I thought that they were pretty cool, except for one thing: they utilized extraneous markup to provide elements to style. Call me a stickler for semantics and separation of content and presentation, but this simply couldn't do. With that in the back of my mind, I went to Tantek's entry page and thought about his hexagons for a while. A hexagon is simply a box of content, with a triangle before and after it. Let me say that again, a triangle :before and :after the content. See where I'm going? Here's an image to demonstrate what was going through my mind at the moment:

A hexagon composed of a rectangle and two triangles

So, does this approach actually work? See for yourself. It was looking at Tantek's hexagons that gave me this insight, so let's do a hexagon to start. Here is his markup:

<ul>
	<li class="o">
		<a href="thelinkurl">
			<b class="h0"></b><b class="h1"></b>
			<span>the link text</span>
		</a>
	</li>
	<-- arbitrary number of list-items -->
</ul>

Ideally, we want something like this:

<ul class="container">
	<li class="hexagon"><a href="thelinkurl">the link text</a></li>
	<!-- arbitrary number of list-items -->
</ul>

Using that exact markup, here is some of the CSS that makes the magic happen:

.hexagon {
	color: #000;
	background: transparent;
	list-style: none;
	float: left;
	width: 10em;
	height: 8.66em
	margin-bottom: 0;
	text-align: center;
	font-family: sans-serif;
}
.hexagon:before {
	/* ensure box is right */
	content: "";
	display: block;
	width: 5em;
	height: 1px;
	line-height: 0;

	/* color the box */
	border-bottom: 4.33em solid #ccc;
	border-left:   2.5em  solid transparent;
	border-right:  2.5em  solid transparent;
}
.hexagon:after {
	/* ensure box is right */
	content: "";
	display: block;
	width: 5em;
	height: 1px;
	line-height: 0;
	margin-bottom: -8.66em;

	/* color the box */
	border-top:   4.33em solid #ccc;
	border-left:  2.5em  solid transparent;
	border-right: 2.5em  solid transparent;
}

All of the colors and sizes are Tantek's. The only thing I claim credit for in that stylesheet is the modification to use :before and :after generated boxes instead of empty, semantically-meaningless markup. Anyway, the result:

I'd say mission accomplished, in Mozilla 1.4-based browsers and Opera 7 at least. There are a few discrepancies between Tantek's and mine (besides his rendering in other browsers), however they are either minor or fixable with more styling. View the source of this page for all of the CSS used to generate this effect.

We're not quite done yet though. A hexagon is easy enough, let's try something else. How about a small triangle in the upper-left, and a small triangle in the lower-right, giving a normal box a slanted look. Here's the markup:

<ul class="cornered">
	<li><h4>Navigation</h4></li>
	<li><a href="/">Home</a></li>
	<li><a href="/articles">Articles</a></li>
	<li><a href="/examples">Examples</a></li>
	<li><a href="/tutorials">Tutorials</a></li>
	<li><a href="/scripts">Scripts</a></li>
	<li><a href="/contact">Contact</a></li>
</ul>

Some CSS:

.cornered {
	font: 0.8em Helvetica, Verdana, Arial, sans-serif;
	background: #039;
	width: 150px;
	margin: 0;
	padding: 0;
}

.cornered:before {
	/* ensure box is right */
	content: "";
	display: marker;
	marker-offset: 0;
	width: 0;
	height: 0;
	line-height: 0;

	/* color the box */
	background: transparent;
	border-style: solid;
	border-top-color: #535d69;
	border-right-color: #039;
	border-width: 20px 10px 0 0;
	
	/* position the box */
	float: left;
	vertical-align: bottom;
}
.cornered:after {
	/* ensure box is right */
	content: "";
	display: marker;
	marker-offset: 0;
	width: 0;
	height: 0;
	line-height: 0;

	/* color the box */
	background: transparent;
	border-style: solid;
	border-top-color: #039;
	border-right-color: #535d69;
	border-width: 20px 10px 0 0;
	
	/* position the box */
	float: right;
	vertical-align: bottom;
}

.cornered > li {
	list-style: none;
	margin: 0 20px;
	padding: 0;
}
.cornered > li > a {
	color: #fff;
	display: block;
	text-decoration: none;
}
.cornered > li > a:hover {
	text-decoration: underline;
}
.cornered > li > h5 {
	font: inherit;
	color: #fff;
	text-align: center;
	margin: 0;
}

The result:

If you thought Mozilla 1.4 and Opera 7 only was too restrictive before, notice that this one only renders in Opera 7. It seems that either there are still some unresolved issues with marker boxes in Gecko, or that perhaps my expected behavior (e.g. Opera 7's) is incorrect.

Anyway, there you go. Slants without extraneous markup in Gecko (recent builds only) and Opera 7. Enjoy.