A Look at :target and How to Make a Tabbed Interface with Just CSS3

February 17, 2012 at 6:40 pm By
Download Demo

Clicking in CSS

I was reading a Sitepoint article on the CSS3 :target pseudo element. It basically allows you to initiate a CSS class by click, with just CSS. This is actually a property that totally went under my radar. @JoeZimJS (who you should definitely follow) mentioned how this could be used to create a tabbed interface, and today that’s what we’re going to do.

Lets Begin

Before we get to the CSS, lets take a look at the HTML.

<div id="tab-box">

	<div id="tab-1" class="tab">
		<span><a href="#tab-1">Tab 1</a></span>
		<span>
		<p>A Little Text </p>
		</span>
	</div>
	<div id="tab-2" class="tab">
		<span><a href="#tab-2">Tab 2</a></span>
		<span>
		<p>Some Text</p>
		</span>
	</div>
	<div id="tab-3" class="tab">
		<span><a href="#tab-3">Tab 3</a></span>
		<span>
		<p>Even More Text</p>
		</span>
	</div>
	

</div>

Each tab contains the span for the actual tab and another span containing the content of that tab. All text and images should be in paragraphs.

CSS

The CSS wasn’t too difficult, but good knowledge of selectors was necessary to do it. I set the body background to a blue color before starting:

background-color: #285996;

Then I added a few styles so everything would align nicely. We’re using inline-blocks so I set font-size to 0 in the parent element so there wouldn’t be gaps between each tab. I changed the font size in child elements to make the fonts legible.



#tab-box {
	width: 390px;
	position: relative;
	font-size: 0;
	font-family: Arial, Helvetica, sans-serif;
}

.tab {
	display: inline-block;
	margin-left: 10px;
	color: #24628b;
}

.tab:first-of-type {
	margin-left: 0;
}
.tab span a:first-of-type {
	cursor: pointer;
	display: inline-block;
	padding: 15px 20px;
	color: #c4d0de;
	border-top-left-radius: 5px;
	border-top-right-radius: 5px;
	text-decoration: none;
	box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);
	background-color: #112338;
	font-size: 18px;
	font-weight: bold;
}

:target

Now lets look at the :target element. Remember we gave each .tab an id earlier? For example, we gave a tab the id tab-1 and the actual tab span link was linked to the id #tab-1. We also gave each tab a class, so what we can say is when the .tab is targeted, we change properties in its children.


.tab:target span:first-of-type a {
	background: #fff;
	box-shadow: none;
	opacity: 1;
	padding: 16px 20px 15px 20px;
	color: #1a2c45;
}
.tab:target span:first-of-type {
	top: 1px;
}

.tab:target span {
	z-index: 5000;
}

I’ve changed a few things, but nothing that difficult to comprehend. Then we finish off by adding a few hover effects and miscellanea

.tab p {
	padding: 0; margin: 0;
	height: 100%;
	overflow: hidden;
	text-align: justify;
}

.tab span:first-of-type {
	position: relative;
}
.tab span a:first-of-type:hover {
	opacity: 1;
}

.tab span:nth-of-type(2) {
	display: block;
	font-size: 14px;
	padding: 20px;
	color: #888;
	line-height: 18px;
	width: 350px;
	height: 250px;
	background: #fff;
	position: absolute;
	left: 0;
}

.tab span:first-of-type a:hover {
	background: #213551;
	color: #fff;
}

.tab:target span:first-of-type a:hover {
	background: #fff;
	color: #1a2c45;
}

And we’re done! I added a single line of Javascript so that the first tab would be targeted automatically.

<script type="text/javascript">
    window.location.hash = '#tab-1'
</script>

Check out the demo below, and click the download link if you wanna save the files for later. Hope you enjoyed this tutorial! Have a good day.