Creating Pure CSS Tabs

One of the things that I like about CSS is that you now have the ability to create self contained pieces of code that would have once relied upon JavaScript. The code below is one such example of pure CSS working alone, with the HTML elements, to produce a tabbed dialog. The code assumes some level of understanding with CSS/HTML. If there are any points that you would like clarified please post a comment.

(click here for demo)

First we need a container to hold the code for the tabs within. This gives us greater control by giving us the opportunity to perform actions on the containers siblings, as well as style the look and feel of the container itself.

<div class="tabs">

A simple div tag is all that’s needed for a container. To this we can apply style to shape our dialog.

.tabs{
    position: relative;
    width: 500px;
    left: calc(50% - 250px);
}

Here we are positioning the container relative to it’s usual position. This does two things. It allows us to place it in the middle of the window but also acts to restrict the positioning of siblings using relative or absolute positioning. This will be required when we get to positioning the tabs. We also specify a width for the container of 500 pixels.

Next we need the HTML code for the tabs.

<div class="tab">
    <input type="radio" name="radio" checked class="radio" id="radio1" />
    <label for="radio1" class="label">Tab1</label>
    <div class="panel">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas, vel, recusandae tenetur fugiat porro consequatur totam architecto  numquam obcaecati excepturi aperiam at sit blanditiis soluta.</p>
        <p>Quo, rem, impedit, fuga at esse cum possimus in doloremque officiis dolor quae voluptatem eos et eius ut cupiditate illum quis deserunt.</p>
    </div>
</div>

Each of the tab elements are grouped in their own div tag container. Within this we have a radio button, a label and another div which holds the content for the tab. The radio button has a unique ID which allows us to tie the label to it using the “for” attribute. We only want the ability to check the radio button but don’t want to see the button itself so will hide it with CSS. The label will become the text on our tab and the content will be hidden in a div tag until the tab (radio button) is clicked. We will duplicate the group of elements for each tab that we require, all held within it’s parent div container, just changing the ID of the radio button each time. Now we can use CSS to style and control the HTML elements.

.radio{
        display: none;
}

First we hide the radio buttons as they will still be checked even when hidden.

.tab{
        float: left;
}

We want all the labels (tabs) to be grouped together on the left so we do this by floating them.

.label{
	cursor: pointer;
	padding: 10px;
	margin: 0;
	font-size: 16px;
	font-weight: bold;
	border: 1px solid #000;
	border-right-width: 0;
	border-bottom-width: 0;
	border-radius: 15px 15px 0 0;
	line-height: 15px;
	height: 15px;
	width: 60px;
	display: inline-block;
	text-align: center;
}

Most of the styling in for the label is pretty self-explanatory. We want a pointer when we move over the label (tab) with some space around the text on the tab. We specify a font and font-style and a border. We only want the border to be one pixel thick so we remove the right border line on each tab. This will leave the last tab on the right needing the right side line but we’ll attend to that in a minute. We also want a radius on the top of the border to curve the tab appearance. Next we specify a height and width for the tab size, align the text to the centre of the tab and finally instruct the browser to draw the elements inline (next to each other from left to right).

Now lets take care of the missing right border on the last tab.

.tabs div:last-child > label{
	border-right-width: 1px;
}

Here we target the label within the last div tag block (tab) in our parent container and simply draw in the missing border line. Now we can concentrate on the actual tab content.

.panel{
	display: none;
	position: absolute;
	left:0;
	border: 1px solid #000;
	padding: 20px;
	height: 220px;
	text-align: justify;
}

This is where our absolute positioning is used. We need to hide the content until the tab (radio button) is checked and the content for each tab needs to be drawn in exactly the same position, relative to its parent. So we can use “position:absolute” and “left: 0” to do this for us. Each block of text within the tab container will be rendered in the same location. All we have to do is show the correct block when the corresponding tab is clicked.

.radio:checked ~ .panel{
	display: block;
}

Here we are instructing the browser to change the display mode from none to block when the radio button is checked. The “~” is used to target the first available “.panel” class element after it, as there are five radio button and five text blocks with a class of “panel”, each contained within a “tab” div block.

Now all that’s left to do is a couple of bits of final dressing.

.label:hover {
	background: #eee;
}
.label:active {
	background: #ccc;
}
.radio:checked + label{
	background-color: #ddd;
}

We want a tab to change colour when we both hover over it (or it’s active) and when we click on it, so a grey for when we hover and a darker grey when we select a tab.

The last piece of CSS is quite important although not always necessary. Due to using absolute positioning within the document, the normal static flow of the document is compromised. This means that if we want to display something after our tabbed dialog we would struggle because the next normal document flow space would be above it. We therefore need a way to bring the starting point for rendering under our tabbed dialog. We are also floating our tabs so we need to clear that first as well.

.tabs:after{
	content: "";
	clear: both;
	height: 262px;
	display: block;
}

This we do with the above pseudo class code. We are clearing the floating element, and although we are not displaying any content with this CSS, we can still give it a height that is more than our tabbed dialog to bring the “block” pointer down below our dialog.

That about sums it up.

FULL CODE

example.css

			.panel{
				display: none;
				position: absolute;
				left:0;
				border: 1px solid #000;
				padding: 20px;
				height: 220px;
				text-align: justify;
			}
			.tabs{
				position: relative;
				width: 500px;
				left: calc(50% - 250px);
			}
			.tabs div:last-child > label{
				border-right-width: 1px;
			}
			.tab{
				float: left;
			}
			.radio{
				display: none;
			}
			.radio:checked + label{
				background-color: #ddd;
			}
			.radio:checked ~ .panel{
				display: block;
			}
			.label{
				cursor: pointer;
				padding: 10px;
				margin: 0px;
				font-size: 16px;
				font-weight: bold;
				border: 1px solid #000;
				border-right-width: 0;
				border-bottom-width: 0;
				border-radius: 15px 15px 0px 0px;
				line-height: 15px;
				height: 15px;
				width: 60px;
				display: inline-block;
				text-align: center;
			}
			.label:hover {
				background: #eee;
			}
			.label:active {
				background: #ccc;
			}

purecsstabs.html


<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>CSS Tabs</title>
		<link rel="stylesheet" href="example.css" />
	</head>
	<body>
		<div class="tabs">
			<div class="tab">
				<input type="radio" name="radio" checked class="radio" id="radio1" />
				<label for="radio1" class="label">Tab1</label>
				<div class="panel">
					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas, vel, recusandae tenetur fugiat porro consequatur totam architecto 	numquam obcaecati excepturi aperiam at sit blanditiis soluta.</p>
					<p>Quo, rem, impedit, fuga at esse cum possimus in doloremque officiis dolor quae voluptatem eos et eius ut cupiditate illum quis deserunt.</p>
				</div>
			</div>
			<div class="tab">
				<input type="radio" name="radio" class="radio" id="radio2" />
				<label for="radio2" class="label">Tab2</label>
				<div class="panel">
					<p>Reiciendis, placeat, harum magni adipisci porro quibusdam provident et sed corrupti dignissimos blanditiis aliquid nisi perspiciatis officia minus dolor a doloremque qui veritatis deserunt veniam!</p>
					<p>Id, aliquam, quo, laboriosam quos repellendus autem ex dicta perspiciatis assumenda voluptates tempora beatae mollitia aperiam doloremque tenetur! Molestiae harum facilis magni?</p>
				</div>
			</div>
			<div class="tab">		
				<input type="radio" name="radio" class="radio" id="radio3" />
				<label for="radio3" class="label">Tab3</label>
				<div class="panel">
					<p>Consequuntur, cumque, dolorem natus harum dolores nulla nemo ipsam illum nihil in non necessitatibus alias omnis dolore provident aliquid reiciendis itaque voluptatum quod qui aperiam!</p>
					<p>Excepturi, aut, vero. Iusto, quaerat mollitia laudantium quia repudiandae necessitatibus incidunt unde corporis rerum aut doloribus eos sit culpa inventore nostrum modi!</p>
				</div>
			</div>
			<div class="tab">
				<input type="radio" name="radio" class="radio" id="radio4" />
				<label for="radio4" class="label">Tab4</label>
				<div class="panel">
					<p>Dolore, sunt, optio unde amet sapiente non quaerat iure quas ipsum voluptates a asperiores vel mollitia harum aperiam aliquid quasi neque dolorem fugiat perferendis quidem?</p>
					<p>Autem, esse, explicabo, aspernatur qui fuga ullam molestiae officiis sapiente labore quo ipsam sequi quaerat et sit quos in fugit iure quisquam.</p>
				</div>
			</div>
			<div class="tab">
				<input type="radio" name="radio" class="radio" id="radio5" />
				<label for="radio5" class="label">Tab5</label>
				<div class="panel">
					<p>Ipsa, debitis, nihil consequatur tempora velit ipsam quod. Veritatis, deserunt, beatae illum magni sunt dolorem ipsa recusandae voluptates error nulla tenetur tempore.</p>
					<p>Nam, magnam, neque laudantium libero rerum dolorem nostrum illum perspiciatis doloribus itaque magni fuga dolor inventore beatae ab. Labore nihil veritatis dolores!</p>
				</div>
			</div>
		</div>
	</body>
</html>

Click Here For Demo or Download Code Here

Special thanks to codecourse.com for many of the techniques used in this code.

Could this happen to you?

Just imagine for a moment that you are trapped by a huge gang of wicked and sadistic captors. You believe 100% that there is no chance of escape – ever – ever! Even a brief look at any one of the gang sends shivers down your spine, adrenaline rushing through your body, absolute terror into your heart. You know that they are going to harm you, to hurt you in some way, but you have no idea when or how. Every moment you follow the orders they give as you tremble all over your body. Have you said something wrong? Did you say something the wrong way? Did they misunderstand what you meant and now you’ll pay the price? You wonder over and over in your mind, “is this the moment they set upon you?” Fear pounds your brain when you hear your name called by one of the unscrupulous leaders. Terror races through your veins causing your heart to beat so hard that you can hear it beating inside your head. The sweat pouring from your brow as you struggle to breath from the shear panic inside. You feel like you are suffocating, like your heart is going to explode, like your stomach is being minced from the inside.

You know without doubt that you are worthless, pathetic, the lowest form of life. You know that you’re a disgrace to your family, a burden to your friends, that you blight society. No-wonder they want to harm you so badly, torment you for their pleasure, and punish you for ever daring to exist.

At night you lay there unable to sleep, like you’re waiting in purgatory for that one voice to call you to your demise… and why shouldn’t they? You are not fit to be part of the human race.

You hear their loud voices laughing like an evil chant. Are they talking about you? Are they planning ways to torture you – ways to trick you into thinking you may actually be safe only to rip you apart the moment your back it turned?

The utter despair rages war on every ounce of your being. As you lay there you know that your life is over already, that this is your everyday, your tomorrow, your forever. You know that you are trapped, that you are totally helpless and completely at the mercy of people whose sole purpose is to thrive on the misery of others.

The sadness in your soul darkens every minute of your existence. Your spirit crushed beyond repair. You will not escape! There is nothing you can do! You know that every day will lead to more terror, more torment, and more torture of your mind as the uncertainty destroys your spirit and quashes every bit of hope you ever had of help, of being free again.

Then it suddenly becomes clear. You feel calm. You know how to get away – how to end the slow and terrifying annihilation of the very fabric that made you the person you once were. There is a way to escape. You do know how to be free – the one way to make sure that they cannot hurt you. After all, your life is already over so why are you living in this hell? You can end it now. There is no point in being alive… is there?

Welcome to the world of mental illness. How do you think you would fare if you were captured?

Understanding is the start of helping sufferers. It is as much an illness as any other. It is very real. It can be crippling. It can be terminal! Don’t you think it’s time the world accepted these facts?

Please give help where you can. Even a tiny gesture can make a massive difference.

©2016 – Adam Hunter

My first post

Welcome to my blog.   Obviously, this is my very first post.   I hope to add more content going forward covering a range of topics that will be open for discussion.

Please keep it clean and on subject if you choose to comment.

Thank you.

Adam