Tạo Tab Bằng CSS (no jquery)

Sử dụng Tab trong thiết kế nội dung rất phổ biến và quen thuộc trong thiết kế web. Trước đây việc làm 1 tab thường sử dụng html , css và kết hợp với js để làm một tab. Hôm nay tôi sẽ trình bày cách tạo ra một tab chỉ dùng HTML và CSS để cho các bạn chưa biết có thể tham khảo

HTML

Sử dụng thuộc tính input để kết nối với lớp chứa nội dung và phần tiêu đề tab được thể hiện trong label

<!-------------HTML Tab ---------------->
<section class="tabs">
    <!------------- Tab ---------------->
    <!------------- Tab 1 ---------------->
    <input id="tab-1" type="radio" name="radio-set" class="tab-selector-1" checked="checked" />
	<label for="tab-1" class="tab-label-1">About us</label>
	<!------------- Tab 2 ---------------->
	<input id="tab-2" type="radio" name="radio-set" class="tab-selector-2" />
	<label for="tab-2" class="tab-label-2">How we work</label>
	<!------------- Tab 3 ---------------->
	<input id="tab-3" type="radio" name="radio-set" class="tab-selector-3" />
	<label for="tab-3" class="tab-label-3">References</label>
    <!------------- Tab 4 ---------------->
	<input id="tab-4" type="radio" name="radio-set" class="tab-selector-4" />
	<label for="tab-4" class="tab-label-4">Contact us</label>
            
	<div class="clear-shadow"></div>
	<!------------- Tab Content ---------------->			
	<div class="content">
        <!------------- Tab Content  1---------------->
		<div class="content-1">
            <p>Some content</p>
		</div>
        <!------------- Tab Content  2---------------->
		<div class="content-2">
            <p>Some content</p>
		</div>
        <!------------- Tab Content  3---------------->
		<div class="content-3">
            <p>Some content</p>
		</div>
        <!------------- Tab Content 4 ---------------->
		<div class="content-4">
            <p>Some content</p>
		</div>
	</div>
</section>

CSS

Mình cho position: relative vì mình muốn di chuyển các thẻ input của nó.

.tabs{
    width:750px;
    margin:0 auto 50px; 
    position:relative;
}

Như ở trên đã nhắc đến .tabs mình cho là relative thì ý đồ của mình cho các thẻ input này là position:absolute với top:0 và left:0 để nó dồn hết về 1 chỗ, sau đó mình cho nó ẩn đi bằng thuộc tính display:none;

.tabs input{
    position:absolute;
    top:0;
    left:0;
    display:none;   
}

Tiếp theo ta sẽ Style cho thẻ label. Đầu tiên mình cho nó là display:block để nó trở thành 1 khối, nhưng mỗi label sẽ nằm trên mỗi dòng cho nên mình sẽ sử dụng thuộc tính float:left để tất cả label nằm trên 1 hàng. Sau đó mình có sử dụng thuộc tính position:relative để sử dụng cho lớp giả (pseudo-class) :after. Các thuộc tính còn lại chủ yếu để style cho Label được bắt mắt hơn thôi, các bạn có thể style theo ý tưởng của mình.

.tabs label{
    display:block;
    float:left;
    position:relative;
    padding:10px 30px;
    line-height:1.5em;
    min-width:55px;
    text-align:center;
    color: #385c5b;
    font-size:13px;
    font-weight:bold;
    text-transform:uppercase;
    letter-spacing:1px;
    cursor:pointer;
    text-shadow:1px 1px 1px rgba(255,255,255,0.3);
    background:-moz-linear-gradient(top, #5ba4a4 0%, #4e8c8a 100%);
    border-radius:5px 5px 0 0;
    box-shadow:2px 0px 2px rgba(0,0,0,0.1),-2px 0 2px rgba(0,0,0,0.1)/*0.1*/
}

Khi ta di chuột vào label thì đối tượng sẽ thay đổi màu nền

.tabs label:hover{
    background:#5ba4a4; 
}

Đoạn code này tôi dùng để che đi phần bóng đổ của thẻ .content div .Các bạn cứ làm theo tôi đi, sau khi hoàn thành sản phẩm các bạn thử xoá đoạn code này đi thì sẽ thấy rõ tác dụng của label:after này. Tôi sẽ giải thích nội dung đoạn code như sau: content để thêm nội dung (xác định nội dung được thêm vào). Display:block để cho nó trở thành 1 khối và có chiều cao(height) là 5px, màu nền (background) là màu trắng (cùng màu với .content div để che đi phần bóng đổ). Sau đó sử dụng left và bottom để di chuyển sao cho hợp lý.

.tabs label:after{
    content:"";
    display:block;
    position:absolute;
    width:100%;
    height:5px;
    background:#fff;
    left:0;
    bottom:-5px;
}

Khi ta float label sang left thì nội dung nó sẽ chạy lên phía trên, nên ta cần sử dụng 1 thẻ div rỗng để cắt ngang phần label và phần nội dung.

.clear-shadow{
    clear:both; 
}

Bây giờ đến phần style cho nội dung. Ở thằng .content này ta cho position:relative để di chuyển các thành phần div con của nó.

.content{
    position:relative;
    width:100%;
z-index:5 !important;
}

Đây chính là các thành phần div con của thằng .content, cứ mỗi nội dung thuộc mỗi tab ta sẽ cho vào 1 thẻ div. Tôi sử dụng position:absolute; top:0;left:0 để gộp nội dung của tất cả thẻ div về 1 vị trí với toạ độ trên = 0 và trái = 0. Ở đây tôi có sử dụng overflow:hidden để che đi những phần dư thừa nằm bên ngoài div và opacity:0 để ẩn các nội dung bên trong div. Thuộc tính transition:opacity .4s để tạo ra hiệu ứng chuyển đổi nội dung cho bắt mắt và nhìn củng mượt hơn.

.content div{
    position:absolute;
    overflow:hidden;
    top:0;
    left:0px;
    opacity:0;
    background:#fff;
    padding:10px 40px 30px; 
    border-radius:0 5px 5px 5px;
    box-shadow: 0 -2px 3px -2px rgba(0,0,0,0.2), 0 2px 2px rgba(0,0,0,0.1); 
    transition:opacity .4s;
}
.content div h2{
    color:#4F8E8E;
    font-size:22px;
}
.content div h3{
    color:#4F8E8E;
    font-size:17px;
}
.content div > p {
    font-style:italic;
    color:#777;
    font-size:13px;
    line-height:1.5em;
    margin:0;
    padding-left:20px;
    border-left:8px solid rgba(63,148,148, 0.1);
}

.tabs input:checked + label{
    background:#fff;
    z-index:6;  
}

Khi thẻ input được checked (được chọn) thì thẻ label có màu nền là màu trắng (để tạo ra sự khác biệt so với các thẻ không được chọn). z-index:6 để nó luôn luôn nằm ở trên không bị các thành phần khác che khuất.

.tabs input.tab-selector-1:checked ~ .content .content-1,
.tabs input.tab-selector-2:checked ~ .content .content-2,
.tabs input.tab-selector-3:checked ~ .content .content-3,
.tabs input.tab-selector-4:checked ~ .content .content-4{
    opacity:1;
z-index:100 !important;
}

Đây chính là đoạn code quan trọng nhất mà củng đơn giản nhất trong bài =))). Ý nghĩa như sau: Opacity:1 cho hiển thị lại các nội dung ở các thẻ .content-1, .content-2, .content-3, .content-4 khi các input.tab-selector-1,i nput.tab-selector-2, input.tab-selector-3, input.tab-selector-4 được checked (được chọn).

Nếu không có thuộc tính z-index:100 thì khi các bạn bôi đen nội dung văn bản của các thẻ About, services, work sẽ không được. Mà chỉ bôi đen được nội dung của thẻ contact thôi vì nó nằm ở trên cùng. Còn z-index:5 là để che đi phần bóng đổ của thẻ content khi được checked.

Dưới đây là link demo code

Xin cảm ơn